Cum conectam o aplicatie MIDlet J2ME la un serviciu Web .NET folosind kSOAP 2

Serviciile web au avut si continua sa aiba un impact mare asupra dezvoltarii aplicatiilor Web deoarece acestea permit independenta totala între clientii si furnizorii de servicii. Locatia, platforma, limbajul de programare si arhitectura clientilor si a celor care ofera serviciile Web nu are niciun efect asupra lor. Tehnologiile Internet si standardele care au permis definirea si utilizarea serviciilor Web sunt Hypertext Transfer Protocol (HTTP), eXtensible Markup Language (XML), Remote Procedure Call (RPC), Web Services Description Language (WSDL), Simple Object Access Protocol (SOAP) si Universal Description, Discovery, & Integration (UDDI).

In acest articol vom vedea cum conectam o aplicatie MIDlet J2ME la un serviciu Web .NET folosind libraria kSOAP 2. Platforma Java 2 Micro Edition (J2ME) ofera suport pentru Web Services prin J2ME Web Services API (WSA), JSR 172, care ofera doua API-uri optionale: invocare de la distanta de servicii (JAX-RPC) si parsare XML (JAXP). Pentru urmatorul exemplu, vom folosi libraria independenta kSOAP 2, pentru ca are un impact minimal asupra performantei aplicatiei si este eficienta. Solutia este dezvoltata în NetBeans IDE, dar se poate folosi, de asemenea, Eclipse IDE.

Pentru a testa solutia J2ME ne vom conecta la un serviciu Web .NET simplu ce publica o metoda pentru adunarea a doua numere întregi. Daca conceptul de serviciu Web .NET este unul nou, puteti obtine informatii in portalul www.asp.net (How Do I: Create and Call a Simple Web Service in ASP.NET). Codul sursa al serviciului Web .NET, WebServiceExample.asmx, este:

namespace itcsolutions
{
    [WebService(Namespace = "http://www.itcsolutions.eu/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]

    public class WebServiceExample : System.Web.Services.WebService
    {

        [WebMethod]
        public int add(int value1, int value2)
        {
            return value1 + value2;
        }
    }
}

1. Descarcati cea mai recenta versiune a librariei kSOAP 2, care este disponibila pe pagina SourceForge a proiectului (http://sourceforge.net/projects/ksoap2/). In acest moment, arhiva librariei kSOAP 2 este ksoap2-J2ME-core-2.1.2.jar.

2. Deschideti NetBeans si creati un nou proiect J2ME (J2ME tutorial – How to create a simple MIDlet application with NetBeans) cu urmatoarele proprietati:

  • Emulator Platform: Java Platform Micro Edition SDK 3.0
  • Device: DefaultCldcPhone1
  • Device Configuration: CLDC-1.1
  • Device Profile: MIDP-2.1

Cum se adauga libraria kSOAP 2 la proiectul J2ME in NetBeans

3. Adaugati libraria kSOAP 2 in proiectul MIDlet:

Cum se adauga libraria  kSOAP intr-un proiect J2ME in NetBeans
Cum se adauga libraria kSOAP intr-un proiect J2ME in NetBeans

3.1 Selectati proiectul J2ME in fereastra Projects din NetBeans. Click-dreapta pe numele proiectului si selectati Properties;

3.2 Selectati categoria Libraries & Resources;

3.3 Click pe butonul Add Jar/Zip… button si selectati libraria kSOAP 2 (ksoap2-j2me-core-2.1.2.jar) descarcata la pasul 1;

3.4. Verificati daca pachetul este bifat si selectati OK. 

4. Creati un MIDlet simplu ((J2ME tutorial – How to create a simple MIDlet application with NetBeans) cu urmatoarele proprietati:

  • MIDlet Name: MidletkSOAP
  • MIDP Class Name: MidletkSOAP
  • Package: eu.itcsolutions.j2me.ksoap

5. Pentru a ne concentra pe modul de utilizare a serviciului .NET, vom defini o interfata simpla, bazata pe un Form, ce contine:

Interfata exemplului kSOAP MIDlet
Interfata exemplului kSOAP MIDlet
  • doua controale de tip TextField utilizate pentru a insera cele doua valori numerice;
  • un StringItem pentru a afisa rezultatul sumei;
  • o comanda Exit (Command) care va inchide MIDlet-ul;
  • o comanda Add (Command) care va apela serviciul Web si va afisa rezultatul sumei;

Toate controalele interfetei sunt definite ca atribute ale clasei MidletkSOAP si sunt initializate in constructorul clasei:

package eu.itcsolutions.j2me.ksoap;

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class MidletkSOAP extends MIDlet {
    //formularul principal
    Form mainForm = null;
    //controalele text-box pentru input
    TextField txtBoxA = null;
    TextField txtBoxB = null;
    //label pentru rezultat
    StringItem result = null;
    //comanda Exit
    Command cmdExit = null;
    //comanda Add
    Command cmdAdd = null;

    //referinta la Display
    Display display = null;

    public MidletkSOAP()
    {
        //construim formularul principal
        mainForm = new Form("kSOAP Example");

        //construim controalele
        txtBoxA = new TextField("Value 1:", null, 5, TextField.NUMERIC);
        txtBoxB = new TextField("Value 2:", null, 5, TextField.NUMERIC);
        result = new StringItem("Result:", null);

        //adaugam controalele la formular
        mainForm.append(txtBoxA);
        mainForm.append(txtBoxB);
        mainForm.append(result);

        //construim comenzile
        cmdExit = new Command("Exit", Command.EXIT, 1);
        cmdAdd = new Command("Add", Command.SCREEN, 1);

        //adaugam comenzile
        mainForm.addCommand(cmdAdd);
        mainForm.addCommand(cmdExit);
    }

    public void startApp() {
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
}
Important !
NU uitati ca pe platforma J2ME, display-ul aplicatiei mobile este controalta de un obiect de tip Display (J2ME tutorial – How to create and display forms and alerts).

In metoda startApp() a MIDlet-ului, ce este apelata cand aplicatia este lansata in executie, initializam referinta Display si afisam formularul anterior.

    public void startApp() {
        //obtinem referinta la Display
        if(display == null)
            display = Display.getDisplay(this);
        //afisam formularul principal
        display.setCurrent(mainForm);
    }

6. Deoarece dorim sa folosim cele doua comenzi definite anterior, Exit si Add, definim handler-ul pentru evenimentul de selectie a unei comenzi prin implementarea interfetei CommandListener si prin supradefinirea metodei abstracte commandAction(Command c, Displayable d):

    public void commandAction(Command c, Displayable d) {
    }

7. In metoda startApp()clasei MidletkSOAP setam formularul astfel incat sa primeasca notificarile de selectie a unei comenzi. Formularul este inregistrat ca handler (command listener)pentru evenimentul respectiv:

        //definime handler-ul pentru selectie comanda
        mainForm.setCommandListener(this);
Important !
Nu uitati sa inregistrati handler-ul pentru eveniment prin apelul metodei setCommandListener(). Implementand interfata CommandListener se defineste doar un posibil handler.

8. Comanda Exit va inchide aplicatia mobila:

    public void commandAction(Command c, Displayable d) {
        if (c == cmdExit) {
            this.destroyApp(false);
            this.notifyDestroyed();
        }
    }

Cum se foloseste libraria kSOAP 2 pentru a se conecta la un serviciu Web .NET dintr-un MIDLet J2ME

Arhitectura solutiei este bazata pe urmatoarele activitati:

Arhitectura solutiei kSOAP MIDlet
Arhitectura solutiei kSOAP MIDlet
  • utilizatorul introduce cele doua valori si selecteaza comanda Add;
  • libraria kSOAP incapsuleaza valorile intr-o cerere SOAP si trimite mesajul catre serviciul Web .NET; trimiterea cererii este evenimentul prin care apelam metoda aflata la distanta;
  • aplicatia primeste raspunsul SOAP ce contine rezultatul apelului metodei remote;
  • utilizand libraria kSOAP, rezultatul este extras din raspuns si este afisat.

9. Vom defini o metoda noua, callWebServiceMethod(), care va incapsula logica si solutia bazata pe kSOAP. Nucleul librariei kSOAP 2 este reprezentat de clasa SoapObject care este folosita pentru a gestiona cererile si raspunsurile SOAP. Obiectul SOAP este descris de:

  • namespace-ul serviciului Web;
  • numele metodei.

In metoda callWebServiceMethod() definim doua constante de tip String, pentru a stoca valorile pentru atributele obiectului SOAP. Cu aceste doua valori construim obiectul SOAP:

//solutia kSOAP
    public void callWebServiceMethod() {
        String NAMESPACE = "http://www.itcsolutions.eu/";
        String METHOD_NAME = "add";

        //construim un obiect SOAP
        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    }

10. Asa cum am vazut in codul sursa aferent serviciului Web .NET , acesta publica metoda add(int a, int b), ce primeste doua valori intregi ca argumente. Parametrii metodei sunt incapsulati in cererea SOAP utilizand metoda addProperty():

        //adaugam argumentele metodei
        request.addProperty("value1",
                Integer.valueOf(txtBoxA.getString()));
        request.addProperty("value2",
                Integer.valueOf(txtBoxB.getString()));

11. Pentru a genera forma XML a cererii SOAP trebuie sa folosim un obiect de tip SoapSerializationEnvelope (din pachetul org.ksoap2.serialization). Cand construim obiectul SoapSerializationEnvelope trebuie sa definim care este versiunea protocolului SOAP utilizat. Pentru serviciul Web .NET din acest exemplu utilizam SOAP 1.1.

Deoarece ne conectam la un serviciu Web .NET initializam proprietatea .dotNet a obiectului SoapSerializationEnvelope cu valoare true.

De asemenea, obiectul SoapObject construit anterior este setat ca mesaj de iesire pentru apelul SOAP.

        SoapSerializationEnvelope envelope =
                new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);

12. Cererea XML SOAP este trimisa peste HTTP folosind un obiect de tip HttpTransport (din pachetul org.ksoap2.transport). Pentru a efectua apelul este nevoie de URL-ul serviciului Web si de actiunea SOAP (definita de namespace-ul serviciului Web si de numele metodei).

        String SOAP_ACTION = "http://www.itcsolutions.eu/add";
        String URL = "http://localhost:50827/WebServiceExample.asmx";

        HttpTransport j2meHttpTransport = new HttpTransport(URL);

13. Din raspunsul SOAP este extras si afisat rezultatul:

        try {
            //pentru debug decomenteaza linia urmatoare
            //j2meHttpTransport.debug = true;
            j2meHttpTransport.call(SOAP_ACTION, envelope);
            SoapObject content = (SoapObject) envelope.bodyIn;
            String sum = content.getProperty(0).toString();

            result.setText(sum);
        } catch (Exception e) {
            e.printStackTrace();
        }

14. Metoda callWebServiceMethod() este apelata cand utilizatorul selecteaza comanda Add:

    public void commandAction(Command c, Displayable d) {
        if (c == cmdExit) {
            this.destroyApp(false);
            this.notifyDestroyed();
        } else if (c == cmdAdd) {
            callWebServiceMethod();
        }
    }

Exemplul complet al aplicatiei kSOAP J2ME este disponibil in fisierul complet al solutiei.

Daca ai probleme cu acest exemplu sau crezi ca nu ai inteles elementele descrise, pune o intrebare in zona de comentarii si iti vom raspunde imediat. De asemenea, orice sugestie sau obervatie care duce la imbunatatirea materialului este bine venita.

Daca ti-a placut sau ti-a fost util acest tutorial atunci spune-le si altora despre el sau arunca-ti o privire pe reclamele din aceasta pagina. Referirea acestui material este cel mai bun mod de a aprecia autorul.