Android Ksoap2 - complex type(request and response)

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

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> 

回答1:

Your UserRequest class needs to implement org.ksoap2.serialization.KvmSerializable.



回答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.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!