【问题标题】:How to create SOAP request via ksoap2如何通过 ksoap2 创建 SOAP 请求
【发布时间】:2012-02-20 03:04:26
【问题描述】:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Header/>
    <S:Body>
        <ns2:FReadStatus xmlns:ns2="http://poweb13/">
            <arg0>000D6F0000</arg0>
        </ns2:FReadStatus>
    </S:Body>
</S:Envelope>

我正在一个 android 项目中工作,我想使用一些 JAX-WS。这些服务是由其他人提供的,所以我无法更改它们中的任何内容。我想用这个书面代码发送上面的 SOAP 消息,但我在调用它们时收到的唯一东西是 java.lang.NullPointerException

private static final String NAMESPACE = "http://poweb13/";
private static final String URL = "http://smart.gr:8080/aWESoME/SmartPlugService?wsdl"; 
private static final String SOAP_ACTION = "SmartPlugService";
private static final String METHOD_NAME = "FReadStatus";
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 
PropertyInfo p1 = new PropertyInfo();
p1.setName("MAC");
p1.setValue("000D6F0000");
p1.setType(myDevice.getmac().toString().getClass());
request.addProperty(p1);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {           
    androidHttpTransport.setXmlVersionTag("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");                 
    androidHttpTransport.call(SOAP_ACTION, envelope);
    SoapObject resultsRequestSOAP = (SoapObject) envelope.bodyIn;
    String result=resultsRequestSOAP.getProperty("return").toString();
    Log.i("info","Received :" + result);
} catch (java.lang.ClassCastException e){
    SoapFault fault=(SoapFault)envelope.bodyIn;
    Log.e("error","Received :" + fault.getMessage().toString());
    Log.e("error","Received :" + fault.getLocalizedMessage().toString());
    StackTraceElement[] st=fault.getStackTrace();
    for(int i=0;i<st.length;i++){
        Log.e("error","Received :" +st[i] );
    }
} catch (Exception e) {
    Log.e("error","smthing went wrong!!");
    e.printStackTrace();
}

我认为它甚至不会创建 xml 文档,但我不知道如何检查它。我试图创建一个 XmlSerializer 来放置用于创建 xml 的数据,但我也收到了 NullPointerException。 那么任何人都可以帮助我如何编码上述请求吗? 这是wsdl文件的一些部分

<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://poweb13/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://poweb13/" name="SmartPlugService">
<types>
<xsd:schema>
<xsd:import namespace="http://poweb13/" schemaLocation="http://smart.gr:8080/aWESoME/SmartPlugService?xsd=1"/>
</xsd:schema>
</types>


<message name="FReadStatus">
<part name="parameters" element="tns:FReadStatus"/>
</message>
...
<portType name="SmartPlugService">
<operation name="FReadStatus">
...
<input wsam:Action="http://poweb13/SmartPlugService/FReadStatusRequest" message="tns:FReadStatus"/>
<output wsam:Action="http://poweb13/SmartPlugService/FReadStatusResponse" message="tns:FReadStatusResponse"/>
<fault message="tns:InvalidDeviceAddressException" name="InvalidDeviceAddressException" wsam:Action="http://poweb13/SmartPlugService/FReadStatus/Fault/InvalidDeviceAddressException"/>
<fault message="tns:InternalServiceException" name="InternalServiceException" wsam:Action="http://poweb13/SmartPlugService/FReadStatus/Fault/InternalServiceException"/>
...
</operation>
</portType>
<binding name="SmartPlugServicePortBinding" type="tns:SmartPlugService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
...
<operation name="FReadStatus">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="InvalidDeviceAddressException">
<soap:fault name="InvalidDeviceAddressException" use="literal"/>
</fault>
<fault name="InternalServiceException">
<soap:fault name="InternalServiceException" use="literal"/>
</fault>
</operation>
...
</binding>

xsd 文件的某些部分

<xs:schema xmlns:tns="http://poweb13/" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0" targetNamespace="http://poweb13/">
<xs:element name="FReadStatus" type="tns:FReadStatus"/>
<xs:complexType name="FReadStatus">
<xs:sequence>
<xs:element name="arg0" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>

我应该有这样的 SOAP 响应:

SOAP Response

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:FReadStatusResponse xmlns:ns2="http://poweb13/">
            <return>1</return>
        </ns2:FReadStatusResponse>
    </S:Body>
</S:Envelope>

【问题讨论】:

    标签: android web-services soap ksoap2


    【解决方案1】:

    好的,所以你有一个函数 FReadStatus:

    <message name="FReadStatus">
      <part name="parameters" element="tns:FReadStatus"/>
    </message>
    

    它有一个复杂类型的元素FReadStatus(即对象,它是在服务器上找到的一个类)
    这个复杂类型有一个字符串类型的属性 arg0。它的定义是:

    <xs:complexType name="FReadStatus">
      <xs:sequence>
        <xs:element name="arg0" type="xs:string" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
    

    因此,您需要创建一个实现 kvmSerializable 的本地类,以将此复杂类型映射到服务器上的相应类,因此您将这样做:

    public class FReadStatus implements KvmSerializable {
    
    String mac; 
    
    @Override
    public Object getProperty(int arg0) {
    switch (arg0){
        case 0:
            return mac;
        default:
            return null;
            }
    }
    
    @Override
    public int getPropertyCount() {
        return 1;//because you have 1 parameter
    }
    
    @Override
    public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
    switch(arg0)
    {
    
        case 0:
            arg2.type = PropertyInfo.STRING_CLASS;//because its type is string
            arg2.name = "arg0";
            break;
        default:break;
    }
    
    }
    
    @Override
    public void setProperty(int arg0, Object arg1) {
    switch(arg0)
    {
        case 0:
            mac=  (String)arg1;
            break;
        default:
            break;
    }
    }
    

    现在你有了类,你将在你拥有的代码中执行以下操作:

        SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME); 
    
        PropertyInfo pi = new PropertyInfo();
        pi.setName("arg0");
        pi.setValue("000D6F0000");
        pi.setType(FReadStatus .class);
        request.addProperty(pi);
    
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 
        envelope.setOutputSoapObject(request);
    
         //Now you have to add mapping to map the local class created, to the one on the server
        envelope.addMapping(NAMESPACE , FReadStatus.class.getSimpleName(), FReadStatus .class);
    
        // Add marshalling (this one might not be necessary, but ill just add it)
        Marshal floatMarshal = new MarshalFloat();
        floatMarshal.register(envelope);
    
        AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);//AndroidHttpTransport INSTEAD OF HttpTransportSE 
    
        androidHttpTransport.debug = true;//NEW ADDED
        try {           
    
            androidHttpTransport.call(SOAP_ACTION, envelope);
    
           //Important Outputs to check how the request/Response looks like.. Check them in Logcat to find these outputs
           System.out.println("requestDump is :"+androidHttpTransport.requestDump);
           System.out.println("responseDump is :"+androidHttpTransport.responseDump);
           System.out.println("response"+envelope.getResponse());
    
        } catch (Exception e){}
    

    让我知道发生了什么。您必须使用Logcat 来检查 requestDump 和 responseDump

    更新:回答您关于 UnknowHostException 的问题
    可能的原因及解决方法

    • 检查您的 AndroidManifest.xml 中是否有:

      <uses-permission android:name="android.permission.INTERNET" />
      
    • 如果您使用的是模拟器,请按照link中的说明进行操作

    • 如果您使用代理,请执行以下操作:

      System.setProperty("http.proxyHost", "my.proxyhost.com");
      System.setProperty("http.proxyPort", "1234");
      
    • 您可能需要对 dns 进行预热,请查看link

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-05
      • 1970-01-01
      • 1970-01-01
      • 2015-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多