java - webservice - ksoap library




Come chiamare un servizio web SOAP su Android (18)

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);
        }

    }
}

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.


È 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;
}

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;
    }

}

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.


Circa un anno fa stavo leggendo questo thread cercando di capire come fare le chiamate SOAP su Android: i suggerimenti per creare il mio utilizzando HttpClient mi hanno portato a creare la mia libreria SOAP per Android:

IceSoap

Fondamentalmente consente di creare buste da inviare tramite una semplice API Java, quindi le analizza automaticamente in oggetti definiti tramite XPath ... ad esempio:

<Dictionary>
    <Id></Id>
    <Name></Name>
</Dictionary>

diventa:

@XMLObject("//Dictionary")
public class Dictionary {
    @XMLField("Id")
    private String id;

    @XMLField("Name")
    private String name;
}

Lo stavo usando per il mio progetto, ma ho pensato che potesse aiutare altre persone, quindi ho passato un po 'di tempo a separarlo ea documentarlo. Mi piacerebbe davvero che alcuni dei tuoi poveri anime che inciampano in questo thread mentre chiacchierano su "SOAP Android" possano provarlo e ottenere qualche beneficio.


Ho avuto il mio tryst con KSOAP; Ho scelto un approccio piuttosto semplice.

Dato un file WSDL, creare modelli di richiesta SOAP per ogni richiesta (ad esempio: utilizzando l'interfaccia utente SOAP) e quindi sostituire i valori da passare nel codice. POST questi dati al punto finale del servizio utilizzando l'istanza DefaultHttpClient e ottieni il flusso di risposta. Analizzare il flusso di risposta utilizzando un parser XML Pull.



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;
    }
}

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.


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.

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();
    }
}

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.


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 ..



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.



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/


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);




wsdl