java ksoap - Come chiamare un servizio web SOAP su Android




library webservice (22)

Sto avendo un sacco di problemi nel trovare buone informazioni su come chiamare un servizio web SOAP / WSDL standard con Android. Tutto quello che sono stato in grado di trovare sono documenti molto contorti e riferimenti a "kSoap2" e poi un po 'di parsing di tutto manualmente con SAX . OK, va bene, ma è il 2008, quindi ho pensato che ci dovrebbe essere una buona libreria per chiamare i servizi web standard.

Il servizio web è fondamentalmente uno creato in NetBeans . Mi piacerebbe avere il supporto IDE per generare le classi idrauliche. Ho solo bisogno del modo più semplice / elegante per contattare un servizio Web basato su WSDL da un telefono basato su Android.


Answers

Seguire questi passaggi con il metodo SOAP

Dal file WSDL,

  • creare modelli di richiesta SOAP per ogni richiesta.

  • Quindi sostituire i valori da passare nel codice.

  • POSTARE questi dati al punto finale del servizio usando l'istanza DefaultHttpClient.

  • Ottieni il flusso di risposta e infine

  • Analizzare il flusso di risposta utilizzando un parser XML Pull.


È possibile eseguire chiamate di sapone come post su http con determinate intestazioni. Ho risolto questa domanda senza librerie aggiuntive come ksoap2 Ecco il codice dal vivo che riceve gli ordini dal servizio di sapone

private static HashMap<String,String> mHeaders = new HashMap<>();

static {
    mHeaders.put("Accept-Encoding","gzip,deflate");
    mHeaders.put("Content-Type", "application/soap+xml");
    mHeaders.put("Host", "35.15.85.55:8080");
    mHeaders.put("Connection", "Keep-Alive");
    mHeaders.put("User-Agent","AndroidApp");
    mHeaders.put("Authorization","Basic Q2xpZW50NTkzMzppMjR3s2U="); // optional
}public final static InputStream receiveCurrentShipments(String stringUrlShipments)
{
    int status=0;
    String xmlstring= "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:ser=\"http://35.15.85.55:8080/ServiceTransfer\">\n" +
            "   <soap:Header/>\n" +
            "   <soap:Body>\n" +
            "      <ser:GetAllOrdersOfShipment>\n" +
            "         <ser:CodeOfBranch></ser:CodeOfBranch>\n" +
            "      </ser:GetAllOrdersOfShipment>\n" +
            "   </soap:Body>\n" +
            "</soap:Envelope>";
    StringBuffer chaine = new StringBuffer("");

    HttpURLConnection connection = null;
    try {
        URL url = new URL(stringUrlShipments);
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestProperty("Content-Length", xmlstring.getBytes().length + "");
        connection.setRequestProperty("SOAPAction", "http://35.15.85.55:8080/ServiceTransfer/GetAllOrdersOfShipment");

        for(Map.Entry<String, String> entry : mHeaders.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            connection.setRequestProperty(key,value);

        }

        connection.setRequestMethod("POST");
        connection.setDoInput(true);

        OutputStream outputStream = connection.getOutputStream();
        outputStream.write(xmlstring.getBytes("UTF-8"));
        outputStream.close();

        connection.connect();
        status = connection.getResponseCode();
    } catch (ProtocolException e) {
        e.printStackTrace();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {

        Log.i("HTTP Client", "HTTP status code : " + status);
    }

    InputStream inputStream = null;
    try {
        inputStream = connection.getInputStream();
    } catch (IOException e) {
        e.printStackTrace();
    }

    return inputStream;
}

org.apache.http.impl.client.DefaultHttpClient viene fornito in Android SDK per impostazione predefinita. Ti connetterò al WSDL.

HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet("http://www.example.com/" + URL);
HttpResponse response = httpClient.execute(httpGet, localContext);

Android non fornisce alcun tipo di libreria SOAP. Puoi scrivere il tuo o usare qualcosa come kSOAP 2 . Come si nota, altri sono stati in grado di compilare e utilizzare kSOAP2 nei propri progetti, ma non ho dovuto.

Google ha dimostrato, fino ad oggi, poco interesse ad aggiungere una libreria SOAP ad Android. Il mio sospetto è che preferiscono supportare le attuali tendenze nei servizi Web verso i servizi basati su REST e utilizzare JSON come formato di incapsulamento dei dati. Oppure, usando XMPP per la messaggistica. Ma questa è solo una congettura.

I servizi Web basati su XML sono un'attività un po 'banale su Android in questo momento. Non conoscendo NetBeans, non posso parlare con gli strumenti disponibili, ma sono d'accordo che una libreria migliore dovrebbe essere disponibile. È possibile che XmlPullParser ti salvi dall'uso di SAX, ma non ne so molto.



SOAP è una tecnologia poco adatta per l'utilizzo su Android (o dispositivi mobili in generale) a causa del sovraccarico di elaborazione / analisi richiesto. Un servizio REST è una soluzione più leggera ed è quello che suggerirei. Android viene fornito con un parser SAX ed è abbastanza semplice da usare. Se è assolutamente necessario gestire / analizzare SOAP su un dispositivo mobile, mi dispiace per te, il miglior consiglio che posso offrire è semplicemente non usare SOAP.


NON DIMENTICARE DI AGGIUNGERE ksoap2.jar nel progetto e aggiungere inoltre l'autorizzazione INTERNET nel file AndroidManifest

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class WebserviceActivity extends Activity {

    private static final String NAMESPACE = "https://api.authorize.net/soap/v1/";
    private static final String URL ="https://apitest.authorize.net/soap/v1/Service.asmx?wsdl"; 
    private static final String SOAP_ACTION = "https://api.authorize.net/soap/v1/AuthenticateTest";
    private static final String METHOD_NAME = "AuthenticateTest";
    private TextView lblResult;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        lblResult = (TextView) findViewById(R.id.tv);

        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 
        request.addProperty("name","44vmMAYrhjfhj66fhJN");
        request.addProperty("transactionKey","9MDQ7fghjghjh53H48k7e7n");
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
        envelope.setOutputSoapObject(request);
        HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
        try {
            androidHttpTransport.call(SOAP_ACTION, envelope);

            //SoapPrimitive  resultsRequestSOAP = (SoapPrimitive) envelope.getResponse();
            // SoapPrimitive  resultsRequestSOAP = (SoapPrimitive) envelope.getResponse();
            SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;


            lblResult.setText(resultsRequestSOAP.toString());
            System.out.println("Response::"+resultsRequestSOAP.toString());


        } catch (Exception e) {
            System.out.println("Error"+e);
        }

    }
}


Se hai problemi con la chiamata al servizio Web in Android, puoi utilizzare il codice seguente per chiamare il servizio web e ottenere risposta. Assicurati che il tuo servizio web restituisca la risposta in Formato tabella dati. Questo codice ti aiuterà se utilizzi dati dal database di SQL Server . Se si utilizza MySQL, è necessario modificare una cosa sostituendo semplicemente la parola NewDataSet dalla frase obj2=(SoapObject) obj1.getProperty("NewDataSet"); da DocumentElement

void callWebService(){ 

private static final String NAMESPACE = "http://tempuri.org/"; // for wsdl it may be package name i.e http://package_name
private static final String URL = "http://localhost/sample/services/MyService?wsdl";
// you can use IP address instead of localhost
private static final String METHOD_NAME = "Function_Name";
private static final String SOAP_ACTION = "urn:" + METHOD_NAME;

    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
    request.addProperty("parm_name", prm_value);// Parameter for Method
    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
    envelope.dotNet = true;// **If your Webservice in .net otherwise remove it**
    envelope.setOutputSoapObject(request);
    HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);

    try {
        androidHttpTransport.call(SOAP_ACTION, envelope);// call the eb service
                                                                                                         // Method
    } catch (Exception e) {
        e.printStackTrace();
    }

    // Next task is to get Response and format that response
    SoapObject obj, obj1, obj2, obj3;
    obj = (SoapObject) envelope.getResponse();
    obj1 = (SoapObject) obj.getProperty("diffgram");
    obj2 = (SoapObject) obj1.getProperty("NewDataSet");

    for (int i = 0; i < obj2.getPropertyCount(); i++) { 
// the method getPropertyCount() and  return the number of rows
            obj3 = (SoapObject) obj2.getProperty(i);
            obj3.getProperty(0).toString();// value of column 1
            obj3.getProperty(1).toString();// value of column 2
            // like that you will get value from each column
        }
    }

Se hai qualche problema in merito, puoi scrivermi ..


Ho creato un nuovo client SOAP per la piattaforma Android. Sta usando un'interfaccia generata da JAX-WS, ma finora è solo una dimostrazione del concetto.

Se sei interessato, prova l'esempio e / o guarda la fonte su AndroidSOAP .


È vero che grazie al suo overhead SOAP non è la scelta migliore per lo scambio di dati con i dispositivi mobili. Tuttavia, potresti trovarti in una situazione in cui non controlli il formato dell'output del server.

Quindi, se devi stare con SOAP, c'è una libreria kSOAP2 con patch per Android qui:
http://code.google.com/p/ksoap2-android/


Suggerirei di verificare uno strumento molto utile che mi ha aiutato molto. Anche i ragazzi che si occupano di quel progetto sono stati molto utili. www.wsdl2code.com/


Scarica e aggiungi il file della libreria SOAP con il tuo progetto Nome file: ksoap2-android-assembly-3.4.0-jar-with-dependencies

Pulisci l'applicazione e avvia il programma

Ecco il codice per la chiamata di servizio SOAP

    String SOAP_ACTION = "YOUR_ACTION_NAME";
    String METHOD_NAME = "YOUR_METHOD_NAME";
    String NAMESPACE = "YOUR_NAME_SPACE";
    String URL = "YOUR_URL";
    SoapPrimitive resultString = null;

    try {
        SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
        addPropertyForSOAP(Request);

        SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        soapEnvelope.dotNet = true;
        soapEnvelope.setOutputSoapObject(Request);

        HttpTransportSE transport = new HttpTransportSE(URL);

        transport.call(SOAP_ACTION, soapEnvelope);
        resultString = (SoapPrimitive) soapEnvelope.getResponse();

        Log.i("SOAP Result", "Result Celsius: " + resultString);
    } catch (Exception ex) {
        Log.e("SOAP Result", "Error: " + ex.getMessage());
    }
    if(resultString != null) {
        return resultString.toString();
    }
    else{
        return "error";
    }

I risultati potrebbero essere JSONObject o JSONArray o String

Per una migliore consultazione, https://trinitytuts.com/load-data-from-soap-web-service-in-android-application/

Grazie.


Pochi mesi fa stavo lavorando con il servizio web jax-ws nell'applicazione j2ee. Stavamo usando CXF wsdl2java per generare lo stub client WS dal file WSDL e con quegli stub client che consumavano i servizi web. Poche settimane fa, quando stavo cercando di consumare il servizio web nello stesso modo in piattaforma Android non ho potuto, perché il jar Android non ha tutti i "jax-ws" che supportano le classi in esso. Quella volta non ho trovato nessuno di questi strumenti (se non fossi riuscito a google in modo efficiente) per soddisfare il mio requisito -

  • Ottenere lo stub del client dal WSDL.
  • E chiama il Servizio con qualche argomento (oggetto richiesta di business java).
  • Ottieni l'oggetto business di risposta.

Così, ho sviluppato il mio strumento di generazione di client SOAP Android . Dove devi seguire questi passaggi:

  • Da WSDL Ottieni Stub client WS, inseriscilo nel tuo progetto.
  • Pronunciare per alcuni servizi "ComplexOperationService", Istanziare il servizio, ottenere la porta dell'endpoint e chiamare il metodo di servizio e ottenere la risposta dal servizio Web:

per esempio:

ComplexOperationService service = new ComplexOperationService( );
ComplexOperation port= service.getComplexOperationPort();    
SomeComplexRequest request = --Get some complex request----;    
SomeComplexResp resp = port.operate( request  );
  • Non è necessario preoccuparsi delle classi di classe di servizio / req / response o di qualsiasi altra classe e del metodo, poiché si sa che sono tutte generate da WSDL.
  • E ovviamente non è necessario essere consapevoli di soap action / envelop / namespace, ecc. Basta chiamare il metodo come noi, gli sviluppatori fanno tutto il tempo.

Per chiamare un servizio Web SOAP da Android, provare a utilizzare questo client

NON DIMENTICARE DI AGGIUNGERE ksoap2-android.jar nel tuo percorso di sviluppo java

public class WsClient {
    private static final String SOAP_ACTION = "somme";
    private static final String OPERATION_NAME = "somme";
    private static final String WSDL_TARGET_NAMESPACE = "http://example.ws";
    private static final String SOAP_ADDRESS = "http://192.168.1.2:8080/axis2/services/Calculatrice?wsdl";

    public String caclculerSomme() {

        String res = null;
        SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE,
                OPERATION_NAME);
        request.addProperty("a", "5");
        request.addProperty("b", "2");

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

        try {
            httpTransport.call(SOAP_ACTION, envelope);
            String result = envelope.getResponse().toString();
            res = result;
            System.out.println("############# resull is :" + result);
        } catch (Exception exception) {
            System.out.println("########### ERRER" + exception.getMessage());
        }

        return res;
    }
}

Questo è un esempio funzionante di consumo di servizi Web SOAP in Android.

** Nota :: *** NON DIMENTICARE DI AGGIUNGERE ksoap2.jar nel progetto e aggiungere inoltre l'autorizzazione INTERNET nel file AndroidManifest *

public final String WSDL_TARGET_NAMESPACE = "http://tempuri.org/";
public final String METHOD_NAME = "FahrenheitToCelsius";
public final String PROPERTY_NAME = "Fahrenheit";
public final String SOAP_ACTION = "http://tempuri.org/FahrenheitToCelsius";
public final String SOAP_ADDRESS = "http://www.w3schools.com/webservices/tempconvert.asmx";


private class TestAsynk extends AsyncTask<String, Void, String> {

    @Override
    protected void onPostExecute(String result) {

        super.onPostExecute(result);
        Toast.makeText(getApplicationContext(),
                String.format("%.2f", Float.parseFloat(result)),
                Toast.LENGTH_SHORT).show();
    }

    @Override
    protected String doInBackground(String... params) {
        SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE,
                METHOD_NAME);
        request.addProperty(PROPERTY_NAME, params[0]);

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

        envelope.setOutputSoapObject(request);

        HttpTransportSE androidHttpTransport = new HttpTransportSE(
                SOAP_ADDRESS);
        Object response = null;
        try {

            androidHttpTransport.call(SOAP_ACTION, envelope);
            response = envelope.getResponse();
            Log.e("Object response", response.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return response.toString();
    }
}


Per me il modo più semplice è usare un buon strumento per generare tutte le classi richieste. Personalmente uso questo sito:

http://easywsdl.com/

Supporta servizi web abbastanza complessi e usa ksoap2.


Aggiungi Soap Libaray ( ksoap2-android-assembly-3.2.0-jar-with-dependencies.jar ):

public static String Fn_Confirm_CollectMoney_Approval (

        HashMap < String, String > str1,
        HashMap < String, String > str2,
        HashMap < String, String > str3) {

    Object response = null;
    String METHOD_NAME = "CollectMoney";
    String NAMESPACE = "http://xxx/yyy/xxx";
    String URL = "http://www.w3schools.com/webservices/tempconvert.asmx";
    String SOAP_ACTION = "";

    try {

        SoapObject RequestParent = new SoapObject(NAMESPACE, METHOD_NAME);

        SoapObject Request1 = new SoapObject(NAMESPACE, "req");

        PropertyInfo pi = new PropertyInfo();

        Set mapSet1 = (Set) str1.entrySet();

        Iterator mapIterator1 = mapSet1.iterator();

        while (mapIterator1.hasNext()) {

            Map.Entry mapEntry = (Map.Entry) mapIterator1.next();

            String keyValue = (String) mapEntry.getKey();

            String value = (String) mapEntry.getValue();

            pi = new PropertyInfo();

            pi.setNamespace("java:com.xxx");

            pi.setName(keyValue);

            pi.setValue(value);

            Request1.addProperty(pi);
        }

        mapSet1 = (Set) str3.entrySet();

        mapIterator1 = mapSet1.iterator();

        while (mapIterator1.hasNext()) {

            Map.Entry mapEntry = (Map.Entry) mapIterator1.next();

            // getKey Method of HashMap access a key of map
            String keyValue = (String) mapEntry.getKey();

            // getValue method returns corresponding key's value
            String value = (String) mapEntry.getValue();

            pi = new PropertyInfo();

            pi.setNamespace("java:com.xxx");

            pi.setName(keyValue);

            pi.setValue(value);

            Request1.addProperty(pi);
        }

        SoapObject HeaderRequest = new SoapObject(NAMESPACE, "XXX");

        Set mapSet = (Set) str2.entrySet();

        Iterator mapIterator = mapSet.iterator();

        while (mapIterator.hasNext()) {

            Map.Entry mapEntry = (Map.Entry) mapIterator.next();

            // getKey Method of HashMap access a key of map
            String keyValue = (String) mapEntry.getKey();

            // getValue method returns corresponding key's value
            String value = (String) mapEntry.getValue();

            pi = new PropertyInfo();

            pi.setNamespace("java:com.xxx");

            pi.setName(keyValue);

            pi.setValue(value);

            HeaderRequest.addProperty(pi);
        }

        Request1.addSoapObject(HeaderRequest);

        RequestParent.addSoapObject(Request1);

        SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER10);

        soapEnvelope.dotNet = false;

        soapEnvelope.setOutputSoapObject(RequestParent);

        HttpTransportSE transport = new HttpTransportSE(URL, 120000);

        transport.debug = true;

        transport.call(SOAP_ACTION, soapEnvelope);

        response = (Object) soapEnvelope.getResponse();

        int cols = ((SoapObject) response).getPropertyCount();

        Object objectResponse = (Object) ((SoapObject) response)
                .getProperty("Resp");

        SoapObject subObject_Resp = (SoapObject) objectResponse;


        modelObject = new ResposeXmlModel();

        String MsgId = subObject_Resp.getProperty("MsgId").toString();


        modelObject.setMsgId(MsgId);

        String OrgId = subObject_Resp.getProperty("OrgId").toString();


        modelObject.setOrgId(OrgId);

        String ResCode = subObject_Resp.getProperty("ResCode").toString();


        modelObject.setResCode(ResCode);

        String ResDesc = subObject_Resp.getProperty("ResDesc").toString();


        modelObject.setResDesc(ResDesc);

        String TimeStamp = subObject_Resp.getProperty("TimeStamp")
                .toString();


        modelObject.setTimestamp(ResDesc);

        return response.toString();

    } catch (Exception ex) {

        ex.printStackTrace();

        return null;
    }

}


Per chiamare un servizio web da un dispositivo mobile (specialmente su un telefono Android), ho usato un modo molto semplice per farlo. Non ho usato alcuna API client di servizi Web nel tentativo di chiamare il servizio web. Il mio approccio è il seguente per effettuare una chiamata.

  1. Creare una semplice connessione HTTP utilizzando l'API standard HttpURLConnection connessione Java.
  2. Formare una richiesta SOAP. (Puoi aiutare SOAPUI a fare una richiesta SOAP).
  3. Imposta il flag doOutPut come vero.
  4. Imposta valori di intestazione HTTP come lunghezza del contenuto, tipo di contenuto e agente utente. Non dimenticare di impostare il valore della lunghezza del contenuto poiché è obbligatorio.
  5. Scrivi tutta la richiesta SOAP nel flusso di output.
  6. Chiama il metodo per stabilire una connessione e ricevere la risposta (nel mio caso ho usato getResonseCode ).
  7. Se il tuo codice di risposta ricevuto come
    1. Significa che sei riuscito a chiamare il servizio web.
  8. Ora prendi un flusso di input sulla stessa connessione HTTP e ricevi l'oggetto stringa. Questo oggetto stringa è una risposta SOAP.
  9. Se il codice di risposta è diverso da 200, prendere un flusso ErrorInput sullo stesso HTTPobject e ricevere l'errore, se presente.
  10. Analizzare la risposta ricevuta utilizzando SAXParser (nel mio caso) o DOMParaser o qualsiasi altro meccanismo di analisi.

Ho implementato questa procedura per il telefono Android e funziona correttamente. Sono in grado di analizzare la risposta anche se è più di 700 KB.


Per aggiungere ulteriori informazioni a questo.

Ho recentemente aggiornato la mia installazione di Ubuntu 10.04 a Ubuntu 10.04 LTS (Lucid Lynx), che a sua volta ha aggiornato la mia versione Java a:

Java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01, mixed mode)

E ora l'emulatore (anche se richiede un po 'di tempo per iniziare) sembra correre più veloce di prima.

Potrebbe valere la pena che le persone aggiornino la loro JVM.





java android web-services soap wsdl