Android Ksoap2 - complex type(request and response)
Solution 1
Your UserRequest class needs to implement org.ksoap2.serialization.KvmSerializable.
Solution 2
I would insist to simply get the response in XML and use any XML Parser to parse the response that would be just easier. Also I would insist you to use ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar
the one you are using is deprecated.
AndroidHttpTransport
is being replaced by HttpTransportSE
Here is how you can get response in XML,
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL, 100);
androidHttpTransport.debug=true;
androidHttpTransport.call(SOAP_ACTION, envelope);
String response = androidHttpTransport.responseDump;
Log.d("Response in XML", response);
You will get the response in response
String and the you can parse it using SAX
or any other XML parser.
Manoj
Updated on June 05, 2022Comments
-
Manoj almost 2 years
I am using ksoap2 to call the java webservice in Android. Java Web service method is,
ImageProcessImpl.java
public UserResponse sample(UserRequest userRequest) { return ImageProcessDAO.sample(userRequest); }
ImageProcessDAO.java
public static String sample(UserRequest userRequest) { System.out.println(userRequest.getClientName()); UserResponse UserResponse = new UserResponse(); userResponse.setMessage("SUCCESS"); return userResponse; }
I am calling these webservices from Android as,
try{ String NAMESPACE = "http://impl.test.com"; String URL = "http://10.0.2.2:8080/Webservice/services/ImageProcessImpl?wsdl"; String SOAP_ACTION = "http://impl.test.com/sample"; String METHOD_NAME = "sample"; SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); UserRequest userRequest = new UserRequest(); userRequest.setClientName("Test"); PropertyInfo pi = new PropertyInfo(); pi.setName("userRequest"); pi.setValue(userRequest); pi.setType(UserRequest.class); request.addProperty(pi); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(request); envelope.implicitTypes = true; envelope.addMapping(NAMESPACE, "UserResponse", UserResponse.class); AndroidHttpTransport httpTransport = new AndroidHttpTransport(URL); httpTransport.debug = true; httpTransport.call(SOAP_ACTION, envelope); UserResponse response = (UserResponse) envelope.getResponse(); Log.e(Test.LOG_TAG, response.getMessage()); }catch (Exception e) { Log.e(Test.LOG_TAG, "throws an exception: " + e.getMessage()); }
But I am getting the error in my Logcat is "throws an exception: Cannot serialize: com.test.common.UserRequest". How to fix this error? Is this right way to call web service with complex type?
my wsdl file is,
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://impl.test.com" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://impl.test.com" xmlns:intf="http://impl.test.com" xmlns:tns1="http://common.test.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!--WSDL created by Apache Axis version: 1.4 Built on Apr 22, 2006 (06:55:48 PDT)--> <wsdl:types> <schema elementFormDefault="qualified" targetNamespace="http://impl.test.com" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://common.test.com"/> <element name="sample"> <complexType> <sequence> <element name="userRequest" type="tns1:UserRequest"/> </sequence> </complexType> </element> <element name="sampleResponse"> <complexType> <sequence> <element name="sampleReturn" type="tns1:UserResponse"/> </sequence> </complexType> </element> </schema> <schema elementFormDefault="qualified" targetNamespace="http://common.test.com" xmlns="http://www.w3.org/2001/XMLSchema"> <complexType name="UserRequest"> <sequence> <element name="clientName" nillable="true" type="xsd:string"/> </sequence> </complexType> <complexType name="UserResponse"> <sequence> <element name="message" nillable="true" type="xsd:string"/> </sequence> </complexType> </schema> </wsdl:types> <wsdl:message name="sampleRequest"> <wsdl:part element="impl:sample" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="sampleResponse"> <wsdl:part element="impl:sampleResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:portType name="ImageProcessImpl"> <wsdl:operation name="sample"> <wsdl:input message="impl:sampleRequest" name="sampleRequest"> </wsdl:input> <wsdl:output message="impl:sampleResponse" name="sampleResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="ImageProcessImplSoapBinding" type="impl:ImageProcessImpl"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="sample"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="sampleRequest"> <wsdlsoap:body use="literal"/> </wsdl:input> <wsdl:output name="sampleResponse"> <wsdlsoap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="ImageProcessImplService"> <wsdl:port binding="impl:ImageProcessImplSoapBinding" name="ImageProcessImpl"> <wsdlsoap:address location="http://localhost:8080/Webservice/services/ImageProcessImpl"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
I used the KvmSerializable. I have added one more array bean variable
private Client[] clientNameList = null;
in UserRequest.java.When I call the web service it is working fine in the request. But in the response I am getting one string that contains all values. The response string is given below.
anyType{clientNameList=anyType{clientNameList=anyType{clientID=1; }; clientNameList=anyType{clientID=2; }; }; message=SUCCESS; }.
How Can I parse this string?
UserResponse.java
public class UserResponse implements KvmSerializable{ public String message = null; public Client[] clientNameList = null; @Override public Object getProperty(int index) { switch (index){ case 0: return message; case 1: return clientNameList; default: return null; } } @Override public int getPropertyCount() { // TODO Auto-generated method stub return 2; } @Override public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) { switch(index) { case 0: info.type = PropertyInfo.STRING_CLASS; info.name = "message"; break; case 1: info.type = PropertyInfo.OBJECT_TYPE; info.name = "clientNameList"; break; default: break; } } @Override public void setProperty(int index, Object value) { switch(index) { case 0: message = value.toString(); break; case 1: clientNameList = (Client[]) value; break; default: break; } } }
Client.java contains only clientId of Integer type.
Updated code and wsdl
ImageProcessImpl.java
public UserResponse sample(UserRequest userRequest) { return ImageProcessDAO.sample(userRequest); }
ImageProcessDAO.java
public static String sample(UserRequest userRequest) { System.out.println(userRequest.getClientName()); UserResponse userResponse = new UserResponse(); userResponse.setMessage(SUCCESS); Client[] clients = new Client[2]; Client client = null; for(int i=0;i<2;i++) { client = new Client(); client.setClientID(i+1); clients[i] = client; } userResponse.setClientNameList(clients); return userResponse; }
I am calling these webservices from Android as,
try{ String NAMESPACE = "http://impl.test.com"; String URL = "http://10.0.2.2:8080/Webservice/services/ImageProcessImpl?wsdl"; String SOAP_ACTION = "http://impl.test.com/sample"; String METHOD_NAME = "sample"; SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); UserRequest userRequest = new UserRequest(); userRequest.setClientName("Test"); PropertyInfo pi = new PropertyInfo(); pi.setName("userRequest"); pi.setValue(userRequest); pi.setType(UserRequest.class); request.addProperty(pi); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(request); envelope.implicitTypes = true; envelope.addMapping(NAMESPACE, "userRequest", UserRequest.class); envelope.addMapping(NAMESPACE, "UserResponse", UserResponse.class); AndroidHttpTransport httpTransport = new AndroidHttpTransport(URL); httpTransport.debug = true; httpTransport.call(SOAP_ACTION, envelope); SoapObject result = (SoapObject) envelope.getResponse(); userResponse.message = result.getProperty(0).toString(); Log.e(Test.LOG_TAG, userResponse.message); }catch (Exception e) { Log.e(Test.LOG_TAG, "throws an exception: " + e.getMessage()); }
my new wsdl file is,
<?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://impl.test.com" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://impl.test.com" xmlns:intf="http://impl.test.com" xmlns:tns1="http://common.test.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!--WSDL created by Apache Axis version: 1.4 Built on Apr 22, 2006 (06:55:48 PDT)--> <wsdl:types> <schema elementFormDefault="qualified" targetNamespace="http://impl.test.com" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://common.test.com"/> <element name="sample"> <complexType> <sequence> <element name="userRequest" type="tns1:UserRequest"/> </sequence> </complexType> </element> <element name="sampleResponse"> <complexType> <sequence> <element name="sampleReturn" type="tns1:UserResponse"/> </sequence> </complexType> </element> <complexType name="ArrayOf_tns1_Client"> <sequence> <element maxOccurs="unbounded" minOccurs="0" name="item" type="tns1:Client"/> </sequence> </complexType> </schema> <schema elementFormDefault="qualified" targetNamespace="http://common.test.com" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://impl.test.com"/> <complexType name="UserRequest"> <sequence> <element name="clientName" nillable="true" type="xsd:string"/> </sequence> </complexType> <complexType name="Client"> <sequence> <element name="clientID" type="xsd:int"/> </sequence> </complexType> <complexType name="UserResponse"> <sequence> <element name="clientNameList" nillable="true" type="impl:ArrayOf_tns1_Client"/> <element name="message" nillable="true" type="xsd:string"/> </sequence> </complexType> </schema> </wsdl:types> <wsdl:message name="sampleRequest"> <wsdl:part element="impl:sample" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:message name="sampleResponse"> <wsdl:part element="impl:sampleResponse" name="parameters"> </wsdl:part> </wsdl:message> <wsdl:portType name="ImageProcessImpl"> <wsdl:operation name="sample"> <wsdl:input message="impl:sampleRequest" name="sampleRequest"> </wsdl:input> <wsdl:output message="impl:sampleResponse" name="sampleResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="ImageProcessImplSoapBinding" type="impl:ImageProcessImpl"> <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="sample"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="sampleRequest"> <wsdlsoap:body use="literal"/> </wsdl:input> <wsdl:output name="sampleResponse"> <wsdlsoap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="ImageProcessImplService"> <wsdl:port binding="impl:ImageProcessImplSoapBinding" name="ImageProcessImpl"> <wsdlsoap:address location="http://localhost:8080/Webservice/services/ImageProcessImpl"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
-
Jaiprakash Soni over 11 yearscan you give response format return from server
-
Manoj over 11 yearsI have added response format(wsdl) in my question.
-
Jaiprakash Soni over 11 yearsYou must check this answer from Theo stackoverflow.com/questions/11907434/…
-
Manoj over 11 yearsI have checked stackoverflow.com/questions/11907434/ksoap2-java-lang-runtimeexception-cannot-serialize. But I got the response from webservice while sending "request.addProperty("variable","value");". When I pass a bean object((i.e) userRequest) as variable I can't invoke the service.
-
-
Manoj over 11 yearsThanks. I will use KvmSerializable and let you know about the result.
-
Manoj over 11 yearsIt is working. The webservice invoked and getting response. But I can't parse the response string.
-
Jason over 11 yearsUserResponse also needs to implement KvmSerializable to be able to "automatically" cast the response to that type. If this is already done and you're getting an error please provide additional details.
-
Manoj over 11 yearsUserResponse also implements KvmSerializable. Still I am getting the issue. I added some additional details in the question. Please check it.
-
Jason over 11 yearsAccording to your wsdl, this is correct - the UserResponse object has a single element, a string named message.
-
Manoj over 11 yearsSorry. I have added one variable in my UserResponse. Now I update my wsdl and code in the question. Now I am getting response as a string " anyType{clientNameList=anyType{clientNameList=anyType{clientID=1; }; clientNameList=anyType{clientID=2; }; }; message=SUCCESS; } ". How can I parse it?
-
Manoj over 11 yearsI used your code. Now I am getting the xml response. Thanks for the help.
-
Manoj over 11 yearsIn my question , "UserResponse.java" I declared "public Client[] clientNameList = null;" and the "getPropertyInfo" method contains "info.type = PropertyInfo.OBJECT_TYPE;" Is is correct? what "info.type" I need to give for the clientNameList ?
-
Lalit Poptani over 11 yearsNow, forget about SOAP parsing(UserResponse.java) simple xml parsing will do. Also you can check my blog post
-
Jason over 11 yearsYou would need to also implement KvmSerializable in your Client class and add a mapping for it in your SoapSerializationEnvelope. To answer your question from the other comment, (if you continue using ksoap), clientNameList would have a type of Vector<Client>.
-
Manoj over 11 yearsthanks. But Client class already implements KvmSerializable. But still I didn't get parsable response. So I used "String response = androidHttpTransport.responseDump;" And I am getting xml response.
-
Manoj over 11 yearsI have added the question about parsing xml into pojo in the the following link "stackoverflow.com/questions/12095437/…". please tell me how can I fix it.
-
Manoj over 11 yearsHai I am getting error while using the kvm serialization. the error posted in "stackoverflow.com/questions/12153053/…". please help me to fix this?
-
Manoj over 11 yearsI am getting error using kvm serialization. I posted the issue in "stackoverflow.com/questions/12153053/…". Please help me to fix this?
-
param over 9 yearsawesome i was not able to get the response in xml format.. now my problem is solved. good job dude.. thanx :)