Tuesday, May 29, 2012

How to call SOAP web service with Android


I am having a lot of trouble finding good information on how to call a standard SOAP/WSDL web service with Android. All I've been able to find are either very convoluted documents and references to "kSoap2" and then some bit about parsing it all manually with SAX . OK, that's fine, but it's 2008 so I figured there should be some good library for calling standard web services.



The web service is just basically one created in NetBeans . I would like to have IDE support for generating the plumbing classes. I just need the easiest/most-elegant way to contact a WSDL based web service from an Android based phone.


Source: Tips4all

19 comments:

  1. Android does not provide any sort of SOAP library. You can either write your own, or use something like kSOAP 2. As you note, others have been able to compile and use kSOAP2 in their own projects, but I haven't had to.

    Google has shown, to date, little interest in adding a SOAP library to Android. My suspicion for this is that they'd rather support the current trends in Web Services toward REST-based services, and using JSON as a data encapsulation format. Or, using XMPP for messaging. But that is just conjecture.

    XML-based web services are a slightly non-trivial task on Android at this time. Not knowing NetBeans, I can't speak to the tools available there, but I agree that a better library should be available. It is possible that the XmlPullParser will save you from using SAX, but I don't know much about that.

    ReplyDelete
  2. org.apache.http.impl.client.DefaultHttpClient comes in the Android SDK by default. That'll get you connected to the WSDL.

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

    ReplyDelete
  3. I hope the video Android WebService01 helps.

    ReplyDelete
  4. It's true that due to it's overhead SOAP is not the best choice for data exchange with mobile devices. However, you might find yourself in situation in which you do not control the format of server output.

    So, if you have to stick with SOAP, there is a kSOAP2 library patched for Android here:
    http://code.google.com/p/ksoap2-android/

    ReplyDelete
  5. SOAP is an ill-suited technology for use on Android (or mobile devices in general) because of the processing/parsing overhead that's required. A REST services is a lighter weight solution and that's what I would suggest. Android comes with a SAX parser, and it's fairly trivial to use. If you are absolutely required to handle/parse SOAP on a mobile device then I feel sorry for you, the best advice I can offer is just not to use SOAP.

    ReplyDelete
  6. To call a web service from a mobile device (especially on an Android phone), I have used a very simple way to do it. I have not used any web service client API in attempt to call the web service. My approach is as follows to make a call.


    Create a simple HTTP connection by
    using the Java standard API
    HttpURLConnection.
    Form a SOAP request. (You can make
    help of SOAPUI to make a SOAP
    request.)
    Set doOutPut flag as true.
    Set HTTP header values like
    content-length, Content
    type, and User-agent. Do not forget
    to set Content-length value as it is a mandatory.
    Write entire the SOAP request to the output stream.
    Call the method to make a connection and
    receive the response (In my case I used
    getResonseCode).
    If your received response code as

    It means you are succeeded to call web service.

    Now take an input stream on the same
    HTTP connection and receive the
    string object. This string object is
    a SOAP response.
    If the response code is other than
    200 then take a ErrorInput stream on
    same HTTPobject and receive the
    error if any.
    Parse the received response
    using SAXParser (in my case) or
    DOMParaser or any other parsing
    mechanism.


    I have implemented this procedure for the Android phone, and it is successfully running. I am able to parse the response even if it is more than 700 KB.

    ReplyDelete
  7. I had my tryst with KSOAP; I chose a rather simpler approach.

    Given a WSDL file, create SOAP Request templates for each Request(for e.g.: using SOAP UI) and then substitute the values to be passed in code. POST this data to the service end point using DefaultHttpClient instance and get the response stream. Parse the Response Stream using an XML Pull parser.

    ReplyDelete
  8. You can have a look at WSClient++

    ReplyDelete
  9. I've created a new SOAP client for the Android platform. It is using a JAX-WS generated interface, but it is only a proof-of-concept so far.

    If you are interested, please try the example and/or watch the source at AndroidSOAP.

    ReplyDelete
  10. If you can, go for JSON. Android comes with the complete org.json package

    ReplyDelete
  11. I hope Calling a web service from Android helps.

    ReplyDelete
  12. Call ksoap2 methods. It works very fine.

    Set up the details, like

    private static String mNAMESPACE=null;
    private static String mURL=null;
    public static Context context=null;


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

    envelope.addMapping(mNAMESPACE, "UserCredentials",new UserCredendtials().getClass());
    AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(mURL);


    and then to get the result do

    androidHttpTransport.call(SOAP_ACTION, envelope);
    result = (SoapPrimitive)envelope.getResponse();

    ReplyDelete
  13. I am sure you could make a little SOAP client with Axis. Axis installation instructions.

    ReplyDelete
  14. About a year ago I was reading this thread trying to figure out how to do SOAP calls on Android - the suggestions to build my own using HttpClient resulted in me building my own SOAP library for Android:

    IceSoap

    Basically it allows you to build up envelopes to send via a simple Java API, then automatically parses them into objects that you define via XPath... for example:

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


    Becomes:

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

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


    I was using it for my own project but I figured it might help some other people so I've spent some time separating it out and documenting it. I'd really love it if some of your poor souls who stumble on this thread while googling "SOAP Android" could give it a go and get some benefit.

    ReplyDelete
  15. I think Call SOAP Web Service from Android application will help you a lot.

    ReplyDelete
  16. If you can use JSON, there is a whitepaper, a video and the sample.code in Developing Application Services with PHP Servers and Android Phone Clients.

    ReplyDelete
  17. If you are having problem regarding calling Web Service in android then
    You can Use below code to call the web service and get response .Make sure that your Web Service return the response in Data Table Format..This code help you if you using data from SQL Server database .If you you using MYSQL you need to change one thing just replace word NewDataSet from sentence obj2=(SoapObject) obj1.getProperty("NewDataSet"); by DocumentElement

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


    If you have any problem regarding this you can write me..

    ReplyDelete
  18. Few months ago I was working with jax-ws web service in j2ee application, There we were using CXF wsdl2java to generate WS client stub from the WSDL file and with those client stubs we consumed the web services. Few weeks ago, when I was trying to consume the web service in the same way in android platform I couldn't, because the android jar has not all the "jax-ws" supporting classes in it. That time I didn't find any such tool ( if I wasn't failed to google efficiently) to meet my requirement --


    Get the client stub from the WSDL.
    And call the Service with some argument (java business request
    object).
    Get the Response Business Object.


    So, I developed my own Android SOAP Client Generation Tool. Where you have to follow these steps :


    From WSDL Get WS Client Stub, Put it in your project.
    Say for Some Service "ComplexOperationService", Instantiate the
    Service, Get the Endpoint port and call the service method, and get the response from the Web service :


    eg:

    ComplexOperationService service = new ComplexOperationService( );
    ComplexOperation port= service.getComplexOperationPort();
    SomeComplexRequest request = --Get some complex request----;
    SomeComplexResp resp = port.operate( request );



    You don't need to care about the service class/req/response classes or any other classes and the method as well, as you know its all are generated from WSDL.
    And of course you needn't be aware of the soap action/envelop/namespace etc. Just call the method as we, developers do all the time.

    ReplyDelete
  19. This example will help a lot,

    public class Login extends Activity {
    /** Called when the activity is first created. */

    private static final String SOAP_ACTION = "http://tempuri.org/LoginUser";
    private static final String METHOD_NAME = "LoginUser";
    private static final String NAMESPACE = "http://tempuri.org/";
    private static final String URL = "http://";
    private static final String TAG = "HELLO";

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Button signin = (Button) findViewById(R.id.regsubmitbtn);

    signin.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
    new StartLoginAsyncTask(yourclass.this).execute();
    }
    });
    }

    private class LoginTask extends AsyncTask<Void, Void, Boolean> {
    private final ProgressDialog dialog = new ProgressDialog(YourClass.this);

    protected void onPreExecute() {
    this.dialog.setMessage("Logging in...");
    this.dialog.show();
    }

    protected Boolean doInBackground(final Void unused) {
    return Main.this.login(); //don't interact with the ui!
    }

    protected void onPostExecute(final Boolean result) {
    if (this.dialog.isShowing()) {
    this.dialog.dismiss();
    }
    if (result.booleanValue()) {
    //also show register success dialog
    }
    }


    }

    ReplyDelete