Search This Blog

Tuesday, July 19, 2011

SOAPy

I've been testing the waters for some Android development. I know I'm late to the party, but we've been seeing more and more demand for mobile apps, so I want to start to get a picture of what it is like. Initial impressions are good (net of some Eclipse weirdness where it seems to forget the library settings on the build path when I restart it sometimes).

The first thing I wanted to do was call a SOAP web service from Android. Yes, SOAP is old school and doesn't make a lot of sense sometimes, but I eventually want to get this working with my SAP NetWeaver systems which speak SOAP. Anyway, the first thing to do was to get a SOAP service running where I can get to it from the Internet.

I'd tried Google App Engine some time ago and thought it was interesting but this gave me a chance to figure out how to create a SOAP web service in GAE. Luckily, there is a tutorial that makes it easy to figure out. Interesting that GAE makes you build all of the gunky plumbing to get this to work (how 2003), but it does work without a lot of trouble or weirdness. So, this code is running at http://l10systems.appspot.com/hellosoapserver. 

Next, it was a matter of figuring out how to call a SOAP web service from Android. There is a library called ksoap2 that does just the trick. It is also pretty old school and you have to take care of some of the plumbing yourself, but it works just fine. I adapted a simple example from Naveen Balani and it just worked. Here is the code:

package com.l10systems.helloandroid;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;


public class HelloAndroid extends Activity {
    private static final String SOAP_ACTION = "http://l10systems.appspot.com/hellosoapserver";
    private static final String GOODBYE_OPERATION_NAME = "sayGoodbye";
    private static final String HELLO_OPERATION_NAME = "sayHello";
    private static final String WSDL_TARGET_NAMESPACE = "http://hellosoap.l10systems.com/";
    private static final String SOAP_ADDRESS = "http://l10systems.appspot.com/hellosoapserver";
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        final Button buttonGoodbye = (Button)findViewById(R.id.button1);
        buttonGoodbye.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                callWebService(GOODBYE_OPERATION_NAME);
            }
        });
        final Button buttonHello = (Button)findViewById(R.id.button2);
        buttonHello.setOnClickListener(new OnClickListener(){
            public void onClick(View v) {
                callWebService(HELLO_OPERATION_NAME);
            }
        });
    }
   
       private void callWebService(String operation) {
        TextView textView = (TextView)findViewById(R.id.textView1);
        //setContentView(textView);
        SoapObject request = new SoapObject(WSDL_TARGET_NAMESPACE, operation );
        request.addProperty("arg0", "Blargh!");
        SoapSerializationEnvelope envelope =
            new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.setOutputSoapObject(request);       
        HttpTransportSE httpTransport = new HttpTransportSE(SOAP_ADDRESS);
        httpTransport.debug = true;
       
        try {
            httpTransport.call(SOAP_ACTION, envelope);
            Object response = envelope.getResponse();
            textView.setText(response.toString());
        } catch (Exception ex){
            textView.setText(ex.toString());
        }
    }
}


This is pretty silly and limited, but it didn't take very long to go from zero to calling a SOAP service in Android. Next steps will be to get the requests running in threads and get some more complex data types moving across the wire.

No comments: