【问题标题】:Android Ksoap2 - complex type(request and response)Android Ksoap2 - 复杂类型(请求和响应)
【发布时间】:2012-08-22 05:16:47
【问题描述】:

我正在使用 ksoap2 在 Android 中调用 java webservice。 Java Web 服务方法是,

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

我将这些来自 Android 的网络服务称为,

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

但我的 Logcat 中出现错误是“引发异常:无法序列化:com.test.common.UserRequest”。如何修复此错误?这是调用复杂类型的 Web 服务的正确方法吗?

我的 wsdl 文件是,

<?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>

我使用了 KvmSerializable。我又添加了一个数组 bean 变量 private Client[] clientNameList = null; 在 UserRequest.java 中。

当我调用 Web 服务时,它在请求中运行良好。但在响应中,我得到一个包含所有值的字符串。响应字符串如下所示。

anyType{clientNameList=anyType{clientNameList=anyType{clientID=1; }; clientNameList=anyType{clientID=2; }; }; message=SUCCESS; }.

如何解析这个字符串?

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 仅包含 Integer 类型的 clientId。

更新的代码和 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;
}

我将这些来自 Android 的网络服务称为,

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

我的新 wsdl 文件是,

<?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>

【问题讨论】:

  • 能否给出服务器返回的响应格式
  • 我在我的问题中添加了响应格式(wsdl)。
  • 您必须检查来自 Theo stackoverflow.com/questions/11907434/…的这个答案
  • 我已经检查了 stackoverflow.com/questions/11907434/ksoap2-java-lang-runtimeexception-cannot-serialize。但是我在发送“request.addProperty("variable","value");"时收到了来自 webservice 的响应。当我将 bean 对象((即)userRequest)作为变量传递时,我无法调用服务。

标签: android web-services ksoap2


【解决方案1】:

我会坚持简单地获取 XML 中的响应并使用任何 XML Parser 来解析更容易的响应。此外,我会坚持您使用 ksoap2-android-assembly-2.5.4-jar-with-dependencies.jar 您正在使用的那个已被弃用。

AndroidHttpTransport 正在被HttpTransportSE 取代

以下是如何在 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);

您将在 response 字符串中获得响应,并且您可以使用 SAX 或任何其他 XML 解析器对其进行解析。

【讨论】:

  • 我使用了你的代码。现在我得到了 xml 响应。感谢您的帮助。
  • 在我的问题中,“UserResponse.java”我声明了“public Client[] clientNameList = null;”并且“getPropertyInfo”方法包含“info.type = PropertyInfo.OBJECT_TYPE;”是正确的吗?我需要为 clientNameList 提供什么“info.type”?
  • 现在,忘记 SOAP 解析(UserResponse.java)简单的 xml 解析就可以了。你也可以查看我的blog post
  • 我在以下链接“stackoverflow.com/questions/12095437/…”中添加了关于将xml解析为pojo的问题。请告诉我如何解决它。
  • 太棒了,我无法获得 xml 格式的响应。现在我的问题解决了。干得好老兄..thanx :)
【解决方案2】:

您的 UserRequest 类需要实现 org.ksoap2.serialization.KvmSerializable。

【讨论】:

  • 谢谢。我将使用 KvmSerializable 并让您知道结果。
  • 它正在工作。调用 Web 服务并获得响应。但我无法解析响应字符串。
  • UserResponse 还需要实现 KvmSerializable 才能“自动”将响应转换为该类型。如果这已经完成并且您收到错误,请提供更多详细信息。
  • UserResponse 也实现了 KvmSerializable。我仍然得到这个问题。我在问题中添加了一些额外的细节。请检查一下。
  • 根据您的 wsdl,这是正确的 - UserResponse 对象有一个元素,一个名为 message 的字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-18
  • 1970-01-01
相关资源
最近更新 更多