2
votes

I'm trying to access a web service whose WSDL is at http://srilanka.lk:9080/services/CropServiceProxy?wsdl . Using SoapUI I sent a request and successfully got a response.

Then using KSoap2 for Android I tried to get a response. But all I get is a SoapFault Error. The code is as follows.

String NAMESPACE = "http://schemas.icta.lk/xsd/crop/handler/v1";

    String URL = "http://www.srilanka.lk:9080/services/CropServiceProxy.CropServiceProxyHttpSoap12Endpoint";

    String method_name = "getCropDataList";
    String SOAP_ACTION = method_name;

    SoapObject request = new SoapObject(NAMESPACE, method_name);
    String crop_code_str = String.valueOf(code.getText().toString());
    System.out.println(crop_code_str);
    System.out.println(request.toString());
    request.addProperty("code", crop_code_str );
    System.out.println(request.getProperty("code").toString());

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
    envelope.setOutputSoapObject(request);

    System.out.println("body out : " + envelope.bodyOut.toString());

    HttpTransportSE http_transport  = new HttpTransportSE(URL);
    try {
        http_transport.call(SOAP_ACTION, envelope);
        System.out.println(envelope.bodyIn.toString());

    } catch (Exception e) {
        e.printStackTrace();
        answer.setText("error caught");
    }

This results in the following.

W/System.err(  394): org.xmlpull.v1.XmlPullParserException: expected: START_TAG {http://www.w3.org/2001/12/soap-envelope}Envelope (position:START_TAG <{http://schemas.xmlsoap.org/soap/envelope/}soapenv:Envelope>@1:114 in java.io.InputStreamReader@43e81258)  

I tried with VER11 but it then gives the following error as the bodyIn.

I/System.out(  365): SoapFault - faultcode: 'soapenv:Server' faultstring: 'org.apache.axis2.databinding.ADBException: Unexpected subelement code' faultactor: 'null' detail: org.kxml2.kdom.Node@43e84648

Is this something wrong with Ksoap2 for android? Then is there another way that a web service can be consumed in Android? (Only SOAP is available)

UPDATE: I tried the KvmSerializable interface for the complext type. Following is my code. I still get the same errors. The XMLPullParser error is being thrown at the http_transport.call line.

This is the complex type implementation at the client side. I have only the WSDL.

public class CropInfo implements KvmSerializable {

    private String name;
    private float price;
    private String location;

    @Override
    public Object getProperty(int arg0) {
        switch (arg0){
        case 0:
            return name;
        case 1:
            return price;
        case 2:
            return location;
        default:
                return null;
        }
    }

    @Override
    public int getPropertyCount() {
        return 3;
    }

    @Override
    public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
        switch (arg0){
        case 0:
            arg2.type = PropertyInfo.STRING_CLASS;
            arg2.name = "Name";
            break;
        case 1:
            arg2.type = Float.class;
            arg2.name = "Price";
            break;
        case 2:
            arg2.type = PropertyInfo.STRING_CLASS;
            arg2.name = "Location";
            break;
        default:
                break;
        }

    }

    @Override
    public void setProperty(int arg0, Object arg1) {
        switch(arg0){
        case 0:
            name = arg1.toString();
            break;
        case 1:
            price = Float.parseFloat(arg1.toString());
        case 2:
            location = arg1.toString();
        default:
            break;
        }
    }
}

The modified code to access and parse the response of the web service.

String NAMESPACE = "http://schemas.icta.lk/xsd/crop/handler/v1/"; String URL = "http://www.srilanka.lk:9080/services/CropServiceProxy.CropServiceProxyHttpSoap12Endpoint"; String method_name = "getCropDataList"; String SOAP_ACTION = "http://schemas.icta.lk/xsd/crop/handler/v1/getCropDataList";

    SoapObject soap_request = new SoapObject(NAMESPACE, method_name);
    String crop_code_str = String.valueOf(code.getText().toString());
    System.out.println(crop_code_str);
    System.out.println(soap_request.toString());
    soap_request.addProperty("code", crop_code_str );
    System.out.println(soap_request.getProperty("code").toString());

    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
    envelope.setOutputSoapObject(soap_request);
    envelope.addMapping(NAMESPACE, "cropInfo", CropInfo.class);
    //envelope.dotNet=true;

    Marshal floatMarshal = new MarshalFloat();
    floatMarshal.register(envelope);

    System.out.println("body out : " + envelope.bodyOut.toString());

    //AndroidHttpTransport http_transport = new AndroidHttpTransport(URL);
    HttpTransportSE http_transport  = new HttpTransportSE(URL);
    try {
                //error comes from this call            
                http_transport.call(SOAP_ACTION, envelope);


        Vector<CropInfo> result_array = (Vector<CropInfo>)envelope.getResponse();
        if(result_array != null){
            for (CropInfo current_crop: result_array){
                System.out.println(current_crop.getName());
                System.out.println(Float.toString(current_crop.getPrice()));
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
        answer.setText("error caught");
    }
3
I'm getting a soap response as <soapenv:Body><soapenv:Fault><faultcode>VersionMismatch</faultcode><faultstring>Only SOAP 1.1 or SOAP 1.2 messages are supported in the system</faultstring><detail /></soapenv:Fault></soapenv:Body>. This is why the XML error happens. But I've used VER12 as SoapUI said the service is soap 1.2chamilad
When I use VER11 I get "org.apache.axis2.databinding.ADBException: Unexpected subelement code" as the response.chamilad
the soap1.2 support only got better with the latest releases. Especially proper SoapFault support for 1.2. Make sure you use the latest release - 2.5.8 from code.google.com/p/ksoap2-android/wiki/HowToUse?tm=2Manfred Moser
Hi Manfred, It was later found out that there was something wrong with the service exposed at their end. They eventually gave out a REST interface with JSON which was much easier to be dealt with.chamilad
maybe you should close or remove the question thenManfred Moser

3 Answers

1
votes

I've read a lot of threads about the pains and inconsistancy of using KSoap. You can use a DefaultHttpClient class to do a http post and just manually make the SOAP header and parse the response.

1
votes

i think your code is ok.

Thirst have a look at your wsdl file, here you can find all the data you need, like namspace, action an so on. In alot of cases action is an emty string like "". I always choos SoapEnvelope.VER11, but normaly it doesn't matter. This code only works with primitiv datatypes and String arrays if you expect complex data you must implement the kvmSerializable interface.

Sorry for my bad english, i hope you understand what i mean. Below is a helpful link.

http://www.drdobbs.com/mobility/208800166;jsessionid=2VAK4K4QQ5H3TQE1GHPSKH4ATMY32JVN?pgno=1

0
votes

KSoap does have a tendancy to insert its own namespaces into each tag, which can give the output you can have a try

envelope.implicitTypes = true;