如何创建通过ksoap2 SOAP请求 [英] How to create SOAP request via ksoap2
问题描述
< XML版本=1.0编码=UTF-8&GT?;
< S:信封XMLNS:S =http://schemas.xmlsoap.org/soap/envelope/>
< S:页眉/>
< S:车身>
< NS2:FReadStatus的xmlns:NS2 =HTTP:// poweb13 />
<为arg0> 000D6F0000< /为arg0>
< / NS2:FReadStatus>
< / S:车身>
< / S:信封>
我在工作中,我要消耗一定的JAX-WS的Android项目。该服务由别人做,所以我不能改变them.I的东西要发送的上述SOAP消息与此书面code,但我收到的时候打电话给他们的唯一事情就是显示java.lang.NullPointerException
私有静态最后弦乐NAMESPACE =HTTP:// poweb13 /;
私有静态最后字符串的URL =http://smart.gr:8080/aWESoME/SmartPlugService?wsdl;
私有静态最后弦乐SOAP_ACTION =SmartPlugService;
私有静态最后弦乐METHOD_NAME =FReadStatus;
SoapObject请求=新SoapObject(命名空间METHOD_NAME);
的PropertyInfo P1 =新的PropertyInfo();
p1.setName(陆委会);
p1.setValue(000D6F0000);
p1.setType(myDevice.getmac()的toString()的getClass());
request.addProperty(p1)为;
SoapSerializationEnvelope包=新SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(要求);
HttpTransportSE androidHttpTransport =新HttpTransportSE(URL);
尝试 {
androidHttpTransport.setXmlVersionTag(&所述;?xml的版本= \1.0 \编码= \UTF-8 \>?);
androidHttpTransport.call(SOAP_ACTION,包);
SoapObject resultsRequestSOAP =(SoapObject)envelope.bodyIn;
字符串结果= resultsRequestSOAP.getProperty(回归)的toString()。
Log.i(信息,接收+结果);
}赶上(java.lang.ClassCastException E){
的SOAPFault故障=(的SOAPFault)envelope.bodyIn;
Log.e(错误,收到:+ fault.getMessage()的toString());
Log.e(错误,收到:+ fault.getLocalizedMessage()的toString());
一个StackTraceElement [] ST = fault.getStackTrace();
的for(int i = 0; I< st.length;我++){
Log.e(错误,收到:+ ST [I]);
}
}赶上(例外五){
Log.e(错误,smthing哪里出了问题!);
e.printStackTrace();
}
我觉得它甚至没有创建一个XML文档,但我不知道如何检查它。我试图创建一个XmlSerializer的将数据创建XML,但我也得到一个NullPointerException异常。 因此,谁能帮助我如何code中的上述要求? 这里的WSDL文件的某些部分。
<定义的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:肥皂=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 >
<类型>
< XSD:架构>
< XSD:导入命名空间=HTTP:// poweb13 /的schemaLocation =http://smart.gr:8080/aWESoME/SmartPlugService?xsd=1/>
< / XSD:模式>
< /类型>
<消息名称=FReadStatus>
<部分名称=参数元素=TNS:FReadStatus/>
< /消息>
...
<端口类型名称=SmartPlugService>
<操作NAME =FReadStatus>
...
<输入WSAM:行动=HTTP:// poweb13 / SmartPlugService / FReadStatusRequest消息=TNS:FReadStatus/>
<输出WSAM:行动=HTTP:// poweb13 / SmartPlugService / FReadStatusResponse消息=TNS:FReadStatusResponse/>
<故障消息=TNS:InvalidDeviceAddressExceptionNAME =InvalidDeviceAddressExceptionWSAM:行动=HTTP:// poweb13 / SmartPlugService / FReadStatus /故障/ InvalidDeviceAddressException/>
<故障消息=TNS:InternalServiceExceptionNAME =InternalServiceExceptionWSAM:行动=HTTP:// poweb13 / SmartPlugService / FReadStatus /故障/ InternalServiceException/>
...
< /运转>
< /端口类型>
<绑定名称=SmartPlugServicePortBindingTYPE =TNS:SmartPlugService>
<肥皂:绑定传输=http://schemas.xmlsoap.org/soap/http的风格=文件/>
...
<操作NAME =FReadStatus>
<肥皂:操作的soapAction =/>
<输入>
<肥皂:身体使用=文字/>
< /输入>
<输出>
<肥皂:身体使用=文字/>
&所述; /输出GT;
<故障名称=InvalidDeviceAddressException>
<肥皂:故障名称=InvalidDeviceAddressException使用=文字/>
< /故障>
<故障名称=InternalServiceException>
<肥皂:故障名称=InternalServiceException使用=文字/>
< /故障>
< /运转>
...
< /装订>
XSD文件的某些部分。
< XS:模式的xmlns:TNS =HTTP:// poweb13 /的xmlns:XS =http://www.w3.org/2001/XMLSchema版本= 1.0的targetNamespace =HTTP:// poweb13 />
< XS:元素的名称=FReadStatusTYPE =TNS:FReadStatus/>
< XS:复杂类型的名称=FReadStatus>
< XS:序列>
< XS:元素的名称=为arg0类型=XS:字符串的minOccurs =0/>
< / XS:序列>
< / XS:复杂类型>
我应该有一个这样的SOAP响应:
SOAP响应
< XML版本=1.0编码=UTF-8&GT?;
< S:信封XMLNS:S =http://schemas.xmlsoap.org/soap/envelope/>
< S:车身>
< NS2:FReadStatusResponse的xmlns:NS2 =HTTP:// poweb13 />
<回归> 1< /回报>
< / NS2:FReadStatusResponse>
< / S:车身>
< / S:信封>
好了,所以你有一个函数FReadStatus:
<消息名称=FReadStatus>
<部分名称=参数元素=TNS:FReadStatus/>
< /消息>
,其具有元件的 FReadStatus 的的复杂类型(即对象,这是在服务器上找到一类)的的。
这复杂类型有一个属性的为arg0 String类型。它的定义是:
< XS:复杂类型的名称=FReadStatus>
< XS:序列>
< XS:元素的名称=为arg0类型=XS:字符串的minOccurs =0/>
< / XS:序列>
< / XS:复杂类型>
所以,你需要创建一个实现 kvmSerializable 以这种复杂类型映射到其对应的类服务器上的本地类,所以你会做什么:
公共类FReadStatus实现KvmSerializable {
字符串MAC;
@覆盖
公共对象的getProperty(INT为arg0){
开关(将arg0){
情况下0:
返回MAC;
默认:
返回null;
}
}
@覆盖
公众诠释getPropertyCount(){
返回1; //因为你有1个参数
}
@覆盖
公共无效为getPropertyInfo(INT为arg0,哈希表ARG1,ARG2的PropertyInfo){
开关(将arg0)
{
情况下0:
arg2.type = PropertyInfo.STRING_CLASS; //因为它的类型为字符串
arg2.name =arg0都;
打破;
默认值:打破;
}
}
@覆盖
公共无效的SetProperty(INT为arg0,对象ARG1){
开关(将arg0)
{
情况下0:
MAC =(字符串)ARG1;
打破;
默认:
打破;
}
}
现在,你有这个类,你会做的code你有以下内容:
SoapObject请求=新SoapObject(命名空间METHOD_NAME);
的PropertyInfo PI =新的PropertyInfo();
pi.setName(arg0都);
pi.setValue(000D6F0000);
pi.setType(FReadStatus的.class);
request.addProperty(PI);
SoapSerializationEnvelope包=新SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(要求);
//现在你必须添加映射到地图创建的本地类,以一个服务器上
envelope.addMapping(命名空间FReadStatus.class.getSimpleName(),FReadStatus的.class);
//添加编组(这个可能不是必要的,但生病只是将它加入)
元帅floatMarshal =新MarshalFloat();
floatMarshal.register(信封);
AndroidHttpTransport androidHttpTransport =新AndroidHttpTransport(URL); // AndroidHttpTransport INSTEAD OF HttpTransportSE
androidHttpTransport.debug = TRUE; //新增
尝试 {
androidHttpTransport.call(SOAP_ACTION,包);
//重要的成果,以检查请求/响应的样子。检查他们在logcat中找到这些输出
的System.out.println(requestDump是:+ androidHttpTransport.requestDump);
的System.out.println(responseDump是:+ androidHttpTransport.responseDump);
的System.out.println(回应+ envelope.getResponse());
}赶上(例外五){}
让我知道,重量发生。您必须使用<一个href="http://stackoverflow.com/questions/3280051/how-to-enable-logcat-console-in-eclipse-for-android">Logcat检查requestDump和responseDump
更新:回答你关于UnknowHostException的问题
可能的原因和解决方法
-
检查一下你的AndroidManifest.xml你有:
&LT;使用-权限的Android:名称=android.permission.INTERNET对/&GT;
-
如果您使用的是仿真器做如本<一个href="http://stackoverflow.com/questions/3514398/android-java-net-unknownhostexception-host-is-unresolved">link
-
如果您是使用代理做的:
System.setProperty(http.proxyHost,my.proxyhost.com); System.setProperty(把http.proxyPort,1234);
-
您可能需要使用预热的DNS,请在此<一个href="http://stackoverflow.com/questions/3293659/android-java-net-unknownhostexception-host-is-unresolved-strategy-question">link
<?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>
i'm working in an android project which i want to consume some JAX-WS. The services are made by someone else so i can't change anything of them.I want to sent the above SOAP message with this written code but the only thing i receive when call them is 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();
}
I think that it doesn't create a xml document even, but i don't know how to check it. I tried to create a XmlSerializer to put data for creating xml but i also receive a NullPointerException. So can anyone help me about how to code the above request? here's some parts of wsdl file
<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>
Some parts of xsd file
<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>
i should have a SOAP response like this:
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>
Ok so you have a function FReadStatus:
<message name="FReadStatus">
<part name="parameters" element="tns:FReadStatus"/>
</message>
which has an element FReadStatus of complex type(ie object, which is a class found on the server).
This complex type has an attribute arg0 of type String. Its definition is:
<xs:complexType name="FReadStatus">
<xs:sequence>
<xs:element name="arg0" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
So you will need to create a local class that implements kvmSerializable to map this complex type to its corresponding class on the server, so you will do :
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;
}
}
Now that you have the class , you will do the following in the code you had:
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){}
Let me know wt happens. You must use Logcat to check requestDump and responseDump
UPDATE: answering your question about UnknowHostException
possible causes and solutions
Check if in your AndroidManifest.xml you have :
<uses-permission android:name="android.permission.INTERNET" />
If you are using an emulator do as mentioned in this link
If you are behind a proxy do :
System.setProperty("http.proxyHost", "my.proxyhost.com"); System.setProperty("http.proxyPort", "1234");
You might need to use warmup the dns , check this link
这篇关于如何创建通过ksoap2 SOAP请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!