十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
android 利用ksoap2方式连接webservice(2010-04-16 16:36:25)转载标签:androidksoap2webserviceit 分类:Android
阜新ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为成都创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!
利用J2SE的ksoap2标准,我也来做一个山寨版本的android连接webservice。因为soap封装的关系,android application在接收到数据后不能够正确的按照J2SE的标准来获取。
在运用之前,我们先要引导两个jar进入工程的buildpath
这两个jar包都可以在网上查到下载,引导完后再做一项准备工作。弄清楚已发布的webservice的地址,以及封装的方式。比如:
webservice接口: (顺便说明一下,在android当中,不能写localhost,必须写清楚PC机当前的网络IP)
webservice封装:
都了解了过后,说明已经做好准备了。
下面就介绍一下android如何获取webservice封装数据。。
引入ksoap2中以封装好的类
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;
在类中定义webservice的接口地址以及解析方式并且定义要调用的webservice中的函数
private static final String URL = " ";
private static final String NAMESPACE = " ";
private static final String METHOD_NAME = "GetMyFriends";
这个信息我们可以在webservice中查到
xs:element name="GetMyFriends"
xs:complexType
xs:sequence
xs:element minOccurs="0" name="userId" type="xs:int"/
xs:element minOccurs="0" name="password" nillable="true" type="xs:string"/
/xs:sequence
/xs:complexType
/xs:element
接下来开始做对webservice请求数据的工作,请求webservice函数以及封装要用的两个参数(userId和password)
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
request.addProperty("userId", "123456");
request.addProperty("password", "test");
之后我们给定义发送数据的信封的封装格式
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11 );
发出请求
envelope.setOutputSoapObject(request);
AndroidHttpTransport aht = new AndroidHttpTransport(URL);
aht.call(null, envelope);
接着就可以定义一个SoapObject类型的实例去获取我们返回来的数据
SoapObject so = (SoapObject) envelope.bodyIn;
这里如果是返回来的数据只有一行并且只有一个值,比如验证函数,返回boolean类型的话,操作比较简单,String getReturn= so.getProperty("return"); 这个getReturn就是你要获取的值。
但是如果返回来是多行的值的话,这个方法就不行了,我们必须对返回来的信息做一些解析。我曾试过用J2SE的标准方式来获取,但是会报错,最主要的可能是他的方式在android当中不能使用。所以在这里我用了正则表达式这种方式来进行数据的解析,我们先来看一下他返回的数据的结构是什么情况。
GetMyFriendsResponse{return=FriendsMessage{ brpermitList=anyType{nickName=我爱罗; singnature=null; userId=2; }; permitList=anyType{nickName=jack; singnature=null; userId=1004; }; permitList=anyType{nickName=admin; singnature=leo_admin; userId=1001; };};}
简单看他很想Json结构,但是确不是。。。
就目前的解决方式,我只是通过规律来进行了正则表达式的解析:如解析上面的内容。
//首先取得permitList(好友)的个数
String testPattern = "permitList";
int resultlength = result.length();
cresult = cresult.replace(testPattern, "");
int lastlength = (resultlength - cresult.length()) / testPattern.length();
//取得每个permitList中的值。
String LoginReturn="", pattern="nickName=.*?;\\s*singnature=.*?;\\s*userId=.*?;";
//动态生成String 数组,存储每个好友的信息
String[] GetFinalReturn = new String[lastlength];
for (int i=0;ilastlength;i++){
LoginReturn = result.replaceFirst("^.*("+pattern+").*$", "$1");
GetFinalReturn[i] = LoginReturn;
result = result.replace(LoginReturn,"");
}
这个数组里面存储的格式就是nickName=admin; singnature=leo_admin; userId=1001;
这样以来,我们可以根据"="和";"两个符号之间做split操作就可以得到数据。
好了,到此连接webservice和解析返回来的数据的工作就做完了,虽然这个方式看起来很复杂,但是目前来说,用ksoap2方式来连接webservice暂时还没有找到更有效的解决方式。。
由于bitmap容易出错,尤其在图片size超大时,而用webview显示图片可以用小避免这个麻烦:
private void showLocalImage(){
final String fileName = "image.png";
final WebView webview_evacuation = (WebView) mView.findViewById(R.id.webview_evacuation);
final LinearLayout ly_map = (LinearLayout) mView.findViewById(R.id.ly_map);
File dir = new File("mnt/sdcard/img/");
if(!dir.exists())
{
dir.mkdir();
}
boolean fileExist = PackageUtil.searchFile(fileName,dir);
if(fileExist){
ViewTreeObserver vto2 = ly_map.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ly_map.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//获取要显示图片的布局宽高
int h = ly_map.getHeight();
int w=ly_map.getWidth();
imageUrl = ""+fileName;
String data = "";
webview_evacuation.loadDataWithBaseURL(imageUrl, data, "text/html", "utf-8", null);
//webview_evacuation.loadUrl(imageUrl);//直接显示网上图片
webview_evacuation.getSettings().setBuiltInZoomControls(true); //显示放大缩小 controler
webview_evacuation.getSettings().setSupportZoom(true); //可以缩放
webview_evacuation.setSaveEnabled(true);
}
});
}
}
其中searchFile方法如下:
public boolean searchFile(String keyword,File filepath)
{
Locale defloc = Locale.getDefault();
try {
if(!filepath.exists())
{
filepath.mkdir();
}
//判断SD卡是否存在
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED))
{
File[] files = filepath.listFiles();
if (files.length 0)
{
for (File file : files)
{
if (file.isDirectory())
{
//如果目录可读就执行(一定要加,不然会挂掉)
if(file.canRead()){
searchFile(keyword,file); //如果是目录,递归查找
}
}
else {
//判断是文件,则进行文件名判断
try {
if (file.getName().indexOf(keyword) -1||file.getName().indexOf(keyword.toUpperCase(defloc)) -1)
{
//存在文件
return true;
}
} catch(Exception e) {
return false;
}
}
}
}
}
} catch (Exception e) {
}
return false;
}
布局很简单:
android:id="@+id/ly_map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/webview_evacuation"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/
转自:
WebView是一个基于webkit引擎、展现web页面的控件。
一般来说Webview可单独使用,可联合其子类一起使用,所以接下来,我会介绍:
常见用法:Back键控制网页后退
WebSettings类
配置步骤2:生成一个WebView组件(有两种方式)
配置步骤3:进行配置-利用WebSettings子类(常见方法)
常见用法:设置WebView缓存
注意: 每个 Application 只调用一次 WebSettings.setAppCachePath(),WebSettings.setAppCacheMaxSize()
常见方法2:onPageStarted()
常见方法3:onPageFinished()
常见方法4:onLoadResource()
常见方法5:onReceivedError()
常见方法6:onReceivedSslError()
常见方法2: onReceivedTitle()
1. 必须确保应用已经添加了网络通信权限
uses-permission android:name="android.permission.INTERNET" /
2. soap请求的URL中的HOST部分不要使用ip地址,使用域名
3. SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
中的SOAP VER要和服务端对应,也可以低于服务端,但是不能高于服务端。
上述三点缺一不可,我讲述一下我的折腾过程供大家参考,
我最初由于马虎,没有做条件1 ,结果会报UnkownHostException,误导我把域名改为IP,
把域名改为IP后,虽然不会报UnkownHostException了,但是会报缺少权限,于是我加上条件1的权限,
加完之后,一切都正确,就总是报 org.xmlpull.v1.XmlPullParserException: expected: START_TAG ,
于是尝试修改SOAP信封版本,VER10 VER11 VER12 三种都试了,无效。
回忆起曾把请求URL中的域名改为IP,于是将IP改回域名,问题解决。
仔细看了一下服务端的版本,是VER11,于是尝试用VER12发送请求,
又报org.xmlpull.v1.XmlPullParserException: expected: START_TAG 了。
尝试用VER10,可以收到正确的response。
两个webview,跟一个是一样的用法,就是使用两个webview控件就行,我在平板项目中加载了四个webview的控件。