Soap 是一种通信协议/基于xml/已被提交至w3c Soap 简介
Soap协议版本有两种 1.1/1.2
For Andorid 对于android而言 有第三方 ksoap2-android
jar包下载 copy至App下libs目录下 add as library 下载地址四个关键参数:
nameSpace/method/SoapAction/Uri
其中SoapAction=nameSpace+method
Uri:.asmx后缀 or .asmx?wsdl
示例:
http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?op=getSupportCityString
POST /WebServices/WeatherWS.asmx HTTP/1.1
Host: ws.webxml.com.cn
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://WebXml.com.cn/getSupportCityString"
这个示例的
Uri:http://ws.webxml.com.cn/WebServices/WeatherWS.asmx
nameSpace:http://WebXml.com.cn/
method:getSupportCityString
看一下简单示例 点击打开链接
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getSupportCityString xmlns="http://WebXml.com.cn/">
<theRegionCode>string</theRegionCode>
</getSupportCityString>
</soap:Body>
</soap:Envelope>
这个示例的传参很简单,方法 getSupportCityString 只有一个参数 theRegionCode
示例代码:
private void soapRequestTest() {
String nameSpace = "http://WebXml.com.cn/";
String methodName = "getSupportCityString";
String soapAction = nameSpace + methodName;
String URI = "http://ws.webxml.com.cn/WebServices/WeatherWS.asmx";
SoapObject request = new SoapObject(nameSpace, methodName);
request.addProperty("theRegionCode", " 4510");
//创建SoapSerializationEnvelope 对象,同时指定soap版本号(之前在wsdl中看到的)
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
envelope.bodyOut = request;//由于是发送请求,所以是设置bodyOut
envelope.dotNet = true;//由于是.net开发的webservice,所以这里要设置为true
HttpTransportSE httpTransportSE = new HttpTransportSE(URI);
try {
httpTransportSE.call(soapAction, envelope);//调用
// 获取返回的数据
if (envelope.bodyIn instanceof SoapFault12) {
SoapFault12 sf = (SoapFault12) envelope.bodyIn;
} else {
SoapObject resultObj = (SoapObject) envelope.bodyIn;
String result = resultObj.toString();
Log.e("Soap", "result : " + result);
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
}
注意该方法调用要在子线程中
new Thread(new Runnable() {
@Override
public void run() {
// soapRequest();
soapRequestTest();
}
}).start();
我们再看一个传参是嵌套的稍微复杂的情况
示例:
POST /xxxx/xx.asmx HTTP/1.1
Host: xx.xx.xx
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/ScheduleGet"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ScheduleGet xmlns="http://tempuri.org/">
<id>
<AdminLoginId>string</AdminLoginId>
<Key>string</Key>
<IsZB>boolean</IsZB>
<TSJWID>string</TSJWID>
</id>
</ScheduleGet>
</soap:Body>
</soap:Envelope>
代码如下:
private void soapRequest() {
String methodName = "ScheduleGet";
String nameSpace = "http://tempuri.org/";
String soapAction = nameSpace + methodName;
String URI = "http://xxx.xx.xx/xx/xx/PKCMSvc.asmx?wsdl";
AuthID bean = new AuthID();
bean.AdminLoginId = "xxx";
bean.Key = "xxxx";
bean.IsZB = true;
bean.TSJWID = "xxx";
PropertyInfo info = new PropertyInfo();
info.setName("id");
info.setValue(bean);
info.namespace = nameSpace;
info.type = PropertyInfo.OBJECT_CLASS;
SoapObject request = new SoapObject(nameSpace, methodName);
request.addProperty(info);
//创建SoapSerializationEnvelope 对象,同时指定soap版本号(之前在wsdl中看到的)
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapSerializationEnvelope.VER11);
envelope.setOutputSoapObject(request);
envelope.bodyOut = request;//由于是发送请求,所以是设置bodyOut
envelope.dotNet = true;//由于是.net开发的webservice,所以这里要设置为true
envelope.addMapping(nameSpace, "AuthID", bean.getClass());
HttpTransportSE httpTransportSE = new HttpTransportSE(URI);
httpTransportSE.debug = true;
try {
httpTransportSE.call(soapAction, envelope);//调用
// 获取返回的数据
if (envelope.bodyIn instanceof SoapFault12) {
SoapFault12 sf = (SoapFault12) envelope.bodyIn;
String faultstring = sf.faultstring;
String faultcode = sf.faultcode;
String message = sf.getMessage();
} else {
SoapObject resultObj = (SoapObject) envelope.bodyIn;
Log.e("webServiceSoap", "result: " + resultObj.toString());
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
}
public class AuthID implements KvmSerializable {
public String AdminLoginId;
public String Key;
public boolean IsZB;
public String TSJWID;
@Override
public Object getProperty(int i) {
switch (i) {
case 0:
return AdminLoginId;
case 1:
return Key;
case 2:
return IsZB;
case 3:
return TSJWID;
default:
break;
}
return null;
}
@Override
public int getPropertyCount() {
return 4;
}
@Override
public void setProperty(int i, Object o) {
// switch (i) {
// case 0:
// AdminLoginId = o.toString();
// break;
// case 1:
// Key = o.toString();
// break;
// case 2:
// IsZB =true;
// break;
// case 3:
// TSJWID = o.toString();
// break;
// default:
// break;
//
// }
}
@Override
public void getPropertyInfo(int i, Hashtable hashtable, PropertyInfo propertyInfo) {
String nameSpace = "http://tempuri.org/";
propertyInfo.namespace = nameSpace;
switch (i) {
case 0:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "AdminLoginId";
break;
case 1:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "Key";
break;
case 2:
propertyInfo.type = PropertyInfo.BOOLEAN_CLASS;
propertyInfo.name = "IsZB";
break;
case 3:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "TSJWID";
break;
default:
break;
}
}
}
AuthID
这里的AuthID 的名称叫法从哪儿来的呢?是从wsdl文档中,你所写的参数名称以及它们对应的type都要严格按照wsdl文档。WSDL文档从哪儿看呢?很简单,在你的URI加上?WSDL 即 xxxx.asmx?wsdl浏览器打开即可。
Java封装写成类 要实现 KvmSerializable 接口。实现里面的四个方法。
info.type = PropertyInfo.OBJECT_CLASS;
type不要写错
参数的大小写不要写错
envelope.addMapping(nameSpace, "AuthID", bean.getClass());
这一行不要漏写
否则,如果参数的顺序写错,参数的类型没有传递,会返回一个
anyType{Text=未将对象引用设置到对象的实例
![](https://i-blog.csdnimg.cn/blog_migrate/d47260f20062b1702babb9106613c79e.png)
总之,要严格按照WSDL文档来写。