我是靠谱客的博主 执着红牛,最近开发中收集的这篇文章主要介绍移动端(安卓)使用webservice访问后端,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在后端使用webservice和移动端交互的时候,移动端(安卓)需要导入一个jar包:ksoap2-android-assembly-3.3.0-jar-with-dependencies或者使用gradle引入也可,
然后自己需要封装webservice去和后端交互,比如这样的:

String namespace = "";
String transUrl = "";
String method = "";
//注意版本使用,这个需要跟后台询问或者从wsdl文档或者服务说明中查看
int envolopeVersion = SoapEnvelope.VER12;
//soapAction是namspace+method拼接
String soapAction = namspace+method;
SoapObject request = new SoapObject(namespace, method);
//参数一定注意要有序,尽管是addProperty(),不要当作HttpUrl可以使用LinkedHashMap封装
request.addProperty("", "");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(envolopeVersion);
envelope.setOutputSoapObject(request);
//envelope.dotNet = true;
HttpTransportSE se = new HttpTransportSE(transUrl);
try {
    //se.call(soapAction, envelope);    //ver11,第一个参数不能为空
    se.call(null, envelope);//envolopeVersion为ver12第一个参数可以为空,必须接口支持ver12才行
    SoapObject response = (SoapObject) envelope.bodyIn;
    //response的处理需要根据返回的具体情况,基本都要进行下面一步
    SoapObject o = (SoapObject) response.getProperty(0);
    //当前方法返回的结果为一个数组
    Log.e("Log", "->" + o.getPropertyCount());
    for (int i = 0; i < o.getPropertyCount(); i++) {
        Log.e("Log", "->" + o.getPropertyAsString(i));
    }
} catch (IOException e) {
    e.printStackTrace();
} catch (XmlPullParserException e) {
    e.printStackTrace();
}


,进行本地化封装后需要自己每次都专门去解析这些响应后的数据,但是接口一旦多了就比较麻烦了

这里有个大牛总结了一个这样的框架:com.github.joaocruz04:jsoap:1.0.2,目前最新版本是1.0.2,
有兴趣的可以去查看下他的源码,但是在源码中我发现了其中一个问题就是在不能解析单个对象,
类似于这样的:
地址为:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?op=getSupportCity

拿到的响应结果为:

HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<getSupportCityResponse xmlns="http://WebXml.com.cn/">
<getSupportCityResult>
<string>string</string>
<string>string</string>
</getSupportCityResult>
</getSupportCityResponse>
</soap12:Body>
</soap12:Envelope>


,经过调试和查看原因是在SoapDeserializer中的setObjectValue没有对这样的特殊的结构进行解析,源码是这样的:

private void setObjectValue(Field f, SoapObject object, String name, boolean isAttribute) {
if (f.getType().equals(String.class)) {
setStringValue(object, name, f, isAttribute);
}
else if (f.getType().equals(Integer.class) || f.getType().equals(int.class)) {
setIntValue(object, name, f, isAttribute);
}
else if (f.getType().equals(Boolean.class) || f.getType().equals(boolean.class)) {
setBooleanValue(object, name, f, isAttribute);
}
else if (f.getType().equals(Double.class) || f.getType().equals(double.class)) {
setDoubleValue(object, name, f, isAttribute);
}
else if (f.getType().equals(Float.class) || f.getType().equals(float.class)) {
setFloatValue(object, name, f, isAttribute);
}
else if (SOAPDeserializable.class.isAssignableFrom(f.getType())) {
setObjectValue(object, name, f, isAttribute);
}
else if (f.getType().isArray()) {
if (f.getType().getComponentType().equals(String.class)) {
setStringArrayValue(object, f);
}
else if (f.getType().getComponentType().equals(Integer.class) || f.getType().getComponentType().equals(int.class)) {
setIntArrayValue(object, f);
}
else if (SOAPDeserializable.class.isAssignableFrom(f.getType().getComponentType())){
setObjectArrayValue(object, f);
}
else if (f.getType().getComponentType().equals(Float.class) || f.getType().getComponentType().equals(float.class)) {
setFloatArrayValue(object, f);
}
else if (f.getType().getComponentType().equals(Double.class) || f.getType().getComponentType().equals(double.class)) {
setDoubleArrayValue(object, f);
}
else if (f.getType().getComponentType().equals(Boolean.class) || f.getType().getComponentType().equals(boolean.class)) {
setBooleanArrayValue(object, f);
}
}
}

还需要在加上对object的处理,这里是修改的方法:

/**
* 给属性赋值
*
* @param originalObjec
* @param f
* @param object
* @param name
* @param isAttribute
*/
private static void setObjectValue(Object originalObjec, Field f, SoapObject object, String name, boolean isAttribute) {
if (f.getType().equals(String.class)) {
setStringValue(originalObjec, object, name, f, isAttribute);
} else if (f.getType().equals(Integer.class) || f.getType().equals(int.class)) {
setIntValue(originalObjec, object, name, f, isAttribute);
} else if (f.getType().equals(Boolean.class) || f.getType().equals(boolean.class)) {
setBooleanValue(originalObjec, object, name, f, isAttribute);
} else if (f.getType().equals(Double.class) || f.getType().equals(double.class)) {
setDoubleValue(originalObjec, object, name, f, isAttribute);
} else if (f.getType().equals(Float.class) || f.getType().equals(float.class)) {
setFloatValue(originalObjec, object, name, f, isAttribute);
} else if (originalObjec.getClass().isAssignableFrom(f.getType())) {
setObjectValue(originalObjec, object, name, f, isAttribute);
} else if (f.getType().isArray()) {
if (f.getType().getComponentType().equals(String.class)) {
setStringArrayValue(originalObjec, object, f);
} else if (f.getType().getComponentType().equals(Integer.class) || f.getType().getComponentType().equals(int.class)) {
setIntArrayValue(originalObjec, object, f);
} else if (f.getType().getComponentType().equals(Float.class) || f.getType().getComponentType().equals(float.class)) {
setFloatArrayValue(originalObjec, object, f);
} else if (f.getType().getComponentType().equals(Double.class) || f.getType().getComponentType().equals(double.class)) {
setDoubleArrayValue(originalObjec, object, f);
} else if (f.getType().getComponentType().equals(Boolean.class) || f.getType().getComponentType().equals(boolean.class)) {
setBooleanArrayValue(originalObjec, object, f);
} else {
setObjectArrayValue(originalObjec, object, f);
}
} else {//这里是新添加的地方,有的类将类作为属性
setObjectValue(originalObjec, object, name, f, isAttribute);
}
}

 

还有在SOAPManager类中的get方法中有一行是这样的:

Object reslt = envelope.getResponse();

这里简答说下:

envelope两种方式获取服务器返回的信息
1.envelope.getResponse();         
2.envelope.bodyIn;

这两种返回的东西是有些区别的

两者的区别:Webservice开发的时候一般情况下大家接受webservice服务器返回值的时候都是使用 
SoapObject soapObject = (SoapObject) envelope.getResponse();这个来接受返回来的值,但这种方法往往会产生java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive这样的错误。

在服务器端返回值是String类型的数值的时候使用SoapObject soapObject = (SoapObject) 
envelope.getResponse()会产生java.lang.ClassCastException: org.ksoap2.serialization.SoapPrimitive这样的错误。
使用SoapObject result = (SoapObject)envelope.bodyIn和 Object object = envelope.getResponse();就可以解决这种错误。

如果服务器返回值的类型是byte[] 的时候,使用Object object = envelope.getResponse();和SoapObject result = (SoapObject)envelope.bodyIn;都不会发生错误现象,但是在使用Object object = envelope.getResponse();取回来的值在使用base64进行解码和编码的时候会报出错误。

如果使用SoapObject result = (SoapObject)envelope.bodyIn;就可以完整的将byte[]进行解码和编码,byte[] ops = Base64.decode(result.getProperty(0).toString());
                SoapObject result=(SoapObject) envelope.bodyIn;
                String str=result.getProperty(0).toString();
                或者是
           Object  result=    (Object) reqVo.envelope.getResponse();
           String str=result.toString();

所以建议将这个

Object reslt = envelope.getResponse();

改为

Object reslt = envelope.bodyIn;

 

如有错误不当之处,望请指正。

转载于:https://my.oschina.net/u/3726375/blog/1793190

最后

以上就是执着红牛为你收集整理的移动端(安卓)使用webservice访问后端的全部内容,希望文章能够帮你解决移动端(安卓)使用webservice访问后端所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部