Question

I'm trying to access a webservice in Android via Ksoap2 for Android.

The SoapObject is created OK, the S.O.P of the bodyOut outputs the desired strings. But when I do a requestDump of the HttpTransportSE object I create to make the call, a NullPointerException happens. In other words, the transport object is null. How can this happen?

Web Service is at http://srilanka.lk:9080/services/CropServiceProxy?wsdl

This service works very well with SoapUI.

SoapUI Request:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v1="http://schemas.icta.lk/xsd/crop/handler/v1/">
   <soap:Header/>
   <soap:Body>
      <v1:getCropDataList>
         <v1:code>ABK</v1:code>
      </v1:getCropDataList>
   </soap:Body>
</soap:Envelope>

SoapUI Response:

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
   <soapenv:Body>
      <ns1:getCropDataListResponse xmlns:ns1="http://schemas.icta.lk/xsd/crop/handler/v1/">
         <ns1:cropInfo>
            <ns1:name>Ambul Kesel</ns1:name>
            <ns1:price>35.0</ns1:price>
            <ns1:location>Dambulla</ns1:location>
         </ns1:cropInfo>
         <ns1:cropInfo>
            <ns1:name>Ambul Kesel</ns1:name>
            <ns1:price>40.0</ns1:price>
            <ns1:location>Dambulla</ns1:location>
         </ns1:cropInfo>
      </ns1:getCropDataListResponse>
   </soapenv:Body>
</soapenv:Envelope>

Client Side Complex Type KvmSerializable implementation:

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

Web Service Call:

public void btnOnClick(View v){
     String NAMESPACE = "http://schemas.icta.lk/xsd/crop/handler/v1/";
  String URL = "http://220.247.225.202: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);
  soap_request.addProperty("code", "ABK" );

  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 {
                    //NullPointerException HERE
   System.out.println(http_transport.requestDump);
   http_transport.call(SOAP_ACTION, envelope);

   //because we should expect a vector, two kinds of prices are given
   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");
   //System.out.println(http_transport.responseDump);
  }

  // String result_string[] = (String[])result;

  //answer.setText("returned");

    }

Can anyone explain this?

Was it helpful?

Solution

You need to set the debug field of the Transport instance to true, then call the call(String,SoapEnvelope) method in order for the requestDump field to be set:

  HttpTransportSE http_transport = new HttpTransportSE(URL);
  http_transport.debug = true;
  try {
   http_transport.call(SOAP_ACTION, envelope);
   System.out.println(http_transport.requestDump);
  //...
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top