第一次遇到soap协议的请求,查了很多资料,尝试了很多次,在最后终于功夫不负有心人,终于调用成功,决定写一篇帖子记录一下,方便以后再次遇到后可以很快想起使用方法。
一、首先要导入Ksoap的jar包
Ksoap下载链接
下载之后放到lib文件夹下,并添加到依赖。
二、开始使用
这里分别介绍两种用法,一种是单一请求参数的简单用法,另一种是将参数封装成对象的方法。
1.单一参数请求
话不多说,直接上代码
// Webservice服务器地址
private static final String SERVER_URL = "http://www.webxml.com.cn/WebServices/WeatherWebService.asmx";
// 调用的webservice命令空间
private static final String PACE = "http://WebXml.com.cn/";
// 获取天气详情的方法名
private static final String W_NAME = "getWeatherbyCityName";
/**
*city 需要查询的城市
*/
public void static getCityWeather(String city){
SoapObject soapObject = new SoapObject(PACE, W_NAME);
soapObject.addProperty("theCityName",city);
final SoapSerializationEnvelope serializa = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
serializa.bodyOut =soapObject;
serializa.dotNet =true;
HttpTransportSE httpSe = new HttpTransportSE(SERVER_URL);
httpSe.debug =true;
httpSe.call(PACE+W_NAME,serializa);
SoapObject result = (SoapObject) serializa.bodyIn;
}
这种方式很简单,以上代码即可请求成功得到一个SoapObject 的对象,然后创建一个对应的天气对象去解析出数据即可,这里可以使用Android自带的pull解析器解析SoapObject 中的xml数据。
对了,写到此处我需要介绍一款好用soap测试工具软件,SoapUI,可以自行搜索下载。
界面是这样的,将server的url粘进去就可以看见所有方法名,参数名,还可以模拟请求,很方便。
2.多参数封装成对象请求
- 创建请求对象实体
public class SoapTestRequest implements KvmSerializable {
private String productID;
private String timeStamp;
private String transactionID;
private String userID;
private int userIDType;
private String userToken;
此处需要实现KvmSerializable,然后复写以下几个方法
@Override
public Object getProperty(int arg0) {
switch (arg0) {
case 0:
return productID;
case 1:
return timeStamp;
case 2:
return transactionID;
case 3:
return userID;
case 4:
return userIDType;
case 5:
return userToken;
default:
break;
}
return null;
}
@Override
public int getPropertyCount() {
return 6;
}
@Override
public void setProperty(int arg0, Object arg1) {
switch (arg0) {
case 0:
productID = arg1.toString();
break;
case 1:
timeStamp = arg1.toString();
break;
case 2:
transactionID = arg1.toString();
break;
case 3:
userID = arg1.toString();
break;
case 4:
userIDType = (int) arg1;
break;
case 5:
userToken = arg1.toString();
break;
default:
break;
}
}
@Override
public void getPropertyInfo(int arg0, Hashtable hashtable, PropertyInfo propertyInfo) {
switch (arg0) {
case 0:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "productID";
break;
case 1:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "timeStamp";
break;
case 2:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "transactionID";
break;
case 3:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "userID";
break;
case 4:
propertyInfo.type = PropertyInfo.INTEGER_CLASS;
propertyInfo.name = "userIDType";
break;
case 5:
propertyInfo.type = PropertyInfo.STRING_CLASS;
propertyInfo.name = "userToken";
break;
default:
break;
}
}
按照上述方式设置相关Property属性,当然后可能还需要get/set方法和toString方法,自行添加。
- 发起请求
这里的步骤和第一种方法就差不多了,还是直接上代码吧
public static void getAuthontication() {
String nameSpace = "http://ip:port/";
String methodName = "serviceAuth";
String soapAction = "http://ip:port/serviceAuth";
String url = "http://ip:port/services/server?wsdl";// 后面加不加那个?wsdl参数影响都不大
SimpleDateFormat format = new SimpleDateFormat();
format.applyPattern("yyyyMMddHHmmss");
final String now = format.format(new Date());
SoapRequest request = new SoapRequest("productID11111",
now,"12345678","ssss11",5,"13333333");
//此处使用以下方式给SoapRequest 传参也是也可以的
// request.setProperty(1, "productID1111");
// request.setProperty(2, now);
// request.setProperty(3, "12345678");
// request.setProperty(4, "sss1111");
// request.setProperty(5, 5);
// request.setProperty(6, "13333333");
// 建立webservice连接对象
HttpTransportSE httpTransportSE = new HttpTransportSE(url);
// 是否是调试模式
httpTransportSE.debug = true;
// 设置连接参数
SoapObject soapObject = new SoapObject(nameSpace, methodName);
PropertyInfo objekt = new PropertyInfo();
objekt.setName("requ");//这个名字可以在SoapUI中找到,xml中包裹参数在最外层的属性名
objekt.setValue(request);
objekt.setType(request.getClass());
soapObject.addProperty(objekt);
// 设置返回参数
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);// soap协议版本必须用SoapEnvelope.VER11(Soap
// V1.1)
envelope.dotNet = true;// 注意:这个属性是对dotnetwebservice协议的支持,如果dotnet的webservice
// 不指定rpc方式则用true否则要用false
envelope.bodyOut = httpTransportSE;
envelope.setOutputSoapObject(soapObject);// 设置请求参数
// new MarshalDate().register(envelope);
envelope.addMapping(nameSpace, "SoapRequest", request.getClass());// 传对象时必须,参数namespace是webservice中指定的,
// claszz是自定义类的类型
try {
httpTransportSE.call(soapAction, envelope);
// SoapObject sb = (SoapObject)envelope.bodyIn;//服务器返回的对象存在envelope的bodyIn中
Object obj = envelope.getResponse();// 直接将返回值强制转换为已知对象
Log.d("WebService", "返回结果:" + obj.toString());
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (Exception ex) {
ex.printStackTrace();
}
}
还是返回的是一个SoapObject对象,解析和上面一样,自己处理,就不过多的赘述了