Android使用ksoap2-android调用WebService学习

    之前主要做客户端UI交互,很少处理数据和接触服务端,但现在的移动设备根本不可能离得开网络连接,数据的交换。最近学习的是在android端如何去调用远程WebService,都说WebService是一种基于SOAP协议的远程调用标准,对于这个协议理解不深,知道webservice可以将不同操作系统平台、不同语言、不同技术整合到一块,android SDK没有直接调用webservice的库,最常用的是借助ksoap2-android这个第三方SDK,点击打开链接,然后和其他第三方jar包一样导入android项目中即可。

        对于WebService服务器具体的编写,现阶段自己不了解,暂且使用网络免费的WebService进行学习http://www.webxml.com.cn/zh_cn/index.aspx,利用这个来写一个简单的国内天气预报的查询,代码编写参照《疯狂Android讲义》相关部分,自己做部分修改。

 

-------------------------------------------------------------------------------------------------------------

       以下是几个主要的方法:

1.创建HttpTransportSE传输对象:HttpTransportSE ht = new HttpTransportSE(SERVICE_URL); SERVICE_URL是webservice提供服务的url

2.使用SOAP1.1协议创建Envelop对象:SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); 设置SOAP协议的版本号,根据服务端WebService的版本号设置。

3.实例化SoapObject对象:SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE, methodName); 第一个参数表示WebService的命名空间,可以从WSDL文档中找到WebService的命名空间。第二个参数表示要调用的WebService方法名。

4.设置调用方法的参数值,如果没有参数,可以省略:例如soapObject.addProperty("theCityCode", cityName);

5.记得设置bodyout属性 envelope.bodyOut = soapObject;

6.调用webservice:ht.call(SERVICE_NAMESPACE+methodName, envelope);

7.获取服务器响应返回的SOAP消息:

     SoapObject result = (SoapObject) envelope.bodyIn;
     SoapObject detail = (SoapObject) result.getProperty(methodName+"Result");

 

-------------------------------------------------------------------------------------------------------------

 

在这个天气预报的demo中需要多次调用webservice,将方法写在一个工具类中,代码如下:

[java]  view plain copy
  1. <span style="font-family:Comic Sans MS;font-size:18px;">package com.example.webservicedemo;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6. import org.ksoap2.SoapEnvelope;  
  7. import org.ksoap2.SoapFault;  
  8. import org.ksoap2.serialization.SoapObject;  
  9. import org.ksoap2.serialization.SoapSerializationEnvelope;  
  10. import org.ksoap2.transport.HttpTransportSE;  
  11. import org.xmlpull.v1.XmlPullParserException;  
  12.   
  13. public class WebServiceUtil {  
  14.     // 定义webservice的命名空间  
  15.     public static final String SERVICE_NAMESPACE = "http://WebXml.com.cn/";  
  16.     // 定义webservice提供服务的url  
  17.     public static final String SERVICE_URL = "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx";  
  18.   
  19.     // 调用远程webservice获取省份列表  
  20.     public static List<String> getProvinceList() {  
  21.         // 调用 的方法  
  22.         String methodName = "getRegionProvince";  
  23.         // 创建HttpTransportSE传输对象  
  24.         HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);  
  25.         try {  
  26.             ht.debug = true;  
  27.             // 使用SOAP1.1协议创建Envelop对象  
  28.             SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(  
  29.                     SoapEnvelope.VER11);  
  30.             // 实例化SoapObject对象  
  31.             SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE,  
  32.                     methodName);  
  33.             envelope.bodyOut = soapObject;  
  34.             // 设置与.NET提供的webservice保持较好的兼容性  
  35.             envelope.dotNet = true;  
  36.   
  37.             // 调用webservice  
  38.             ht.call(SERVICE_NAMESPACE + methodName, envelope);  
  39.             if (envelope.getResponse() != null) {  
  40.                 // 获取服务器响应返回的SOAP消息  
  41.                 SoapObject result = (SoapObject) envelope.bodyIn;  
  42.                 SoapObject detail = (SoapObject) result.getProperty(methodName  
  43.                         + "Result");  
  44.                 // 解析服务器响应的SOAP消息  
  45.                 return parseProvinceOrCity(detail);  
  46.             }  
  47.         } catch (SoapFault e) {  
  48.             // TODO Auto-generated catch block  
  49.             e.printStackTrace();  
  50.         } catch (IOException e) {  
  51.             // TODO Auto-generated catch block  
  52.             e.printStackTrace();  
  53.         } catch (XmlPullParserException e) {  
  54.             // TODO Auto-generated catch block  
  55.             e.printStackTrace();  
  56.         }  
  57.         return null;  
  58.     }  
  59.   
  60.     // 根据省份获取城市列表  
  61.     public static List<String> getCityListsByProvince(String province) {  
  62.         // 调用的方法  
  63.         String methodName = "getSupportCityString";  
  64.         // 创建httptransportSE传输对象  
  65.         HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);  
  66.         ht.debug = true;  
  67.         // 实例化SoapObject对象  
  68.         SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE, methodName);  
  69.         // 添加一个请求参数  
  70.         soapObject.addProperty("theRegionCode", province);  
  71.         // 使用soap1.1协议创建envelop对象  
  72.         SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(  
  73.                 SoapEnvelope.VER11);  
  74.         envelope.bodyOut = soapObject;  
  75.         // 设置与.NET提供的webservice保持较好的兼容性  
  76.         envelope.dotNet = true;  
  77.   
  78.         // 调用webservice  
  79.         try {  
  80.             ht.call(SERVICE_NAMESPACE + methodName, envelope);  
  81.             if (envelope.getResponse() != null) {  
  82.                 // 获取服务器响应返回的SOAP消息  
  83.                 SoapObject result = (SoapObject) envelope.bodyIn;  
  84.                 SoapObject detail = (SoapObject) result.getProperty(methodName  
  85.                         + "Result");  
  86.                 // 解析服务器响应的SOAP消息  
  87.                 return parseProvinceOrCity(detail);  
  88.             }  
  89.         } catch (SoapFault e) {  
  90.             // TODO Auto-generated catch block  
  91.             e.printStackTrace();  
  92.         } catch (IOException e) {  
  93.             // TODO Auto-generated catch block  
  94.             e.printStackTrace();  
  95.         } catch (XmlPullParserException e) {  
  96.             // TODO Auto-generated catch block  
  97.             e.printStackTrace();  
  98.         }  
  99.         return null;  
  100.     }  
  101.   
  102.     // 解析省份或城市  
  103.     public static List<String> parseProvinceOrCity(SoapObject detail) {  
  104.         ArrayList<String> result = new ArrayList<String>();  
  105.         for (int i = 0; i < detail.getPropertyCount(); i++) {  
  106.             // 解析出每个省份  
  107.             result.add(detail.getProperty(i).toString().split(",")[0]);  
  108.         }  
  109.         return result;  
  110.     }  
  111.   
  112.     // 根据城市字符串获取相应天气情况  
  113.     public static SoapObject getWeatherByCity(String cityName) {  
  114.         String methodName = "getWeather";  
  115.         HttpTransportSE ht = new HttpTransportSE(SERVICE_URL);  
  116.         ht.debug = true;  
  117.         SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(  
  118.                 SoapEnvelope.VER11);  
  119.         SoapObject soapObject = new SoapObject(SERVICE_NAMESPACE, methodName);  
  120.         soapObject.addProperty("theCityCode", cityName);  
  121.         envelope.bodyOut = soapObject;  
  122.         envelope.dotNet = true;  
  123.   
  124.         try {  
  125.             ht.call(SERVICE_NAMESPACE + methodName, envelope);  
  126.             SoapObject result = (SoapObject) envelope.bodyIn;  
  127.             SoapObject detail = (SoapObject) result.getProperty(methodName  
  128.                     + "Result");  
  129.             return detail;  
  130.         } catch (IOException e) {  
  131.             // TODO Auto-generated catch block  
  132.             e.printStackTrace();  
  133.         } catch (XmlPullParserException e) {  
  134.             // TODO Auto-generated catch block  
  135.             e.printStackTrace();  
  136.         }  
  137.         return null;  
  138.     }  
  139.   
  140. }  
  141.   
  142.   
  143. </span>  


SoapObject 解析



//当返回值为数组对象

SoapObject result = (SoapObject) envelope.bodyIn;
for (int i = 0; i < result.getPropertyCount(); i++) {
SoapObject child = (SoapObject) result.getProperty(i);
ProduceScanInfo produce = new ProduceScanInfo();

produce.setDepartment(child.getProperty("department").toString());
produce.setEmployeeNo(child.getProperty("employeeNo").toString());
produce.setEmployee(child.getProperty("employee").toString());
produce.setOrderno(child.getProperty("orderno").toString());
produce.setProductname(child.getProperty("productname").toString());
produce.setColor(child.getProperty("color").toString());
produce.setSize(child.getProperty("size").toString());
produce.setColorno(child.getProperty("colorno").toString());
produce.setWorkname(child.getProperty("workname").toString());
produce.setPackno(Integer.parseInt(child.getProperty("packno").toString()));
produce.setNumber(Integer.parseInt(child.getProperty("number").toString()));  
System.out.println(produce);
   list.add(produce);
}


//返回值为boolean

public boolean isExistUser(String sql) {
this.setMethodName("isExistUser");
initConfig(sql);
Object soapObject = null;


if (envelope.bodyIn instanceof SoapFault) {
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("", str);
} else {


try {
soapObject = (Object) envelope.getResponse();
} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}
return Boolean.parseBoolean(soapObject.toString());
}




上面这个便是主要实现远程调用webservice的代码,其他实现在activity中完成即可,但是这里也会涉及到一个问题,就是Android多线程问题,在调用webservice时,为了防止ANR的出现,不能在主线程中进行,需要另开子线程执行,,因为子线程涉及到UI更新,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的.便要涉及Handler的使用了,实在是不才,自己更多时候习惯使用AsyncTask来代替Handler(还是要重新琢磨下Handler的使用方法),因为操作起来比较简单方便,下面是项目中异步操作类中的一个:

 

[java]  view plain copy
  1. <span style="font-family:Comic Sans MS;font-size:18px;">package com.example.webservicedemo;  
  2.   
  3. import java.util.List;  
  4. import android.os.AsyncTask;  
  5. import android.widget.Spinner;  
  6.   
  7. public class ProvinceAsyncTask extends AsyncTask<String, String, List<String>> {  
  8.     private MainActivity activity;  
  9.     private List<String> provinces;  
  10.     private Spinner sp_province;  
  11.       
  12.     public ProvinceAsyncTask (MainActivity activity,Spinner sp_province){  
  13.         this.activity = activity;  
  14.         this.sp_province = sp_province;  
  15.     }  
  16.   
  17.     @Override  
  18.     protected List<String> doInBackground(String... params) {   
  19.         // TODO Auto-generated method stub  
  20.         provinces = WebServiceUtil.getProvinceList();  
  21.         return null;  
  22.     }  
  23.   
  24.     @Override  
  25.     protected void onPostExecute(List<String> result) {  
  26.         // TODO Auto-generated method stub  
  27.         ListAdapter adapter = new ListAdapter(activity, provinces);  
  28.         sp_province.setAdapter(adapter);  
  29.           
  30.     }  
  31. }  
  32.   
  33.   
  34. </span>  


可以看出来比较简单,在doInBackground中执行调用webservice,在onPostExecute中执行列表刷新展示

 


报错:

Could not find class 'org.ksoap2.serialization.SoapObject', referenced from method com.neusoft.kunming.WebservercallActivity.getWeather

java.lang.NoClassDefFoundError: org.ksoap2.serialization.SoapObject


解决方法: 导入ksoap2.jar,最后不要忘记一定要用 Add External Jars... 不能用Add Jars

然后要在Orader and Export 钩选你的ksoap2.jar,否则不会导出到APK


 

最后附上该demo的代码,希望可以对初涉及android调用webservice的朋友有帮助

http://download.csdn.net/detail/eyu8874521/5609627



SOAP解析实例



package com.nautinus.sop;


import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Properties;
import java.util.ResourceBundle;


import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;


import android.util.Log;


import com.nautinus.activity.R;
import com.nautinus.bean.Machines;
import com.nautinus.bean.MachinesMaintain;
import com.nautinus.bean.User;


public class SopExquery {


private String nameSpace = "http://util.boda.com";
private String serviceUrl = "http://192.168.5.44:5678/axis2/services/NautiusQueryService?wsdl";
private String methodName;
private SoapSerializationEnvelope envelope;


private ArrayList<Machines> list = new ArrayList<Machines>();
private ArrayList<MachinesMaintain> maintainlist = new ArrayList<MachinesMaintain>();


public String getNameSpace() {
return nameSpace;
}


public void setNameSpace(String nameSpace) {
this.nameSpace = nameSpace;
}


public String getMethodName() {
return methodName;
}


public void setMethodName(String methodName) {
this.methodName = methodName;
}


public String getServiceUrl() {
return serviceUrl;
}


public void setServiceUrl(String serviceUrl) {
this.serviceUrl = serviceUrl;
}


public void initConfig(String sql) {


SoapObject request = new SoapObject(nameSpace, methodName);
request.addProperty("sql", sql);


envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = request;


HttpTransportSE ht = new HttpTransportSE(serviceUrl);
ht.debug = true;
try {
ht.call(nameSpace + methodName, envelope);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}


/**
* 查询机器状态

* @param sql
* @return
*/


public ArrayList<Machines> query(String sql) {


this.setMethodName("executeMachineStateQuery");
initConfig(sql);


if (envelope.bodyIn instanceof SoapFault) {
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("", str);


} else {
SoapObject result = (SoapObject) envelope.bodyIn;
for (int i = 0; i < result.getPropertyCount(); i++) {


SoapObject child = (SoapObject) result.getProperty(i);
System.out.println(child);
Machines produce = new Machines();


if (child.getProperty("roomCode") == null) {


produce.setRoomCode(" ");
} else {
produce.setRoomCode(child.getProperty("roomCode")
.toString());
}


if (child.getProperty("groupCode") == null) {


produce.setGroupCode(" ");
} else {
produce.setGroupCode(child.getProperty("groupCode")
.toString());
}


if (child.getProperty("machCode") == null) {


produce.setMachCode(-1);
} else {
produce.setMachCode(Integer.parseInt(child.getProperty(
"machCode").toString()));
}


if (child.getProperty("state") == null) {


produce.setState(-1);
} else {
produce.setState(Integer.parseInt(child
.getProperty("state").toString()));
}


System.out.println(produce);
list.add(produce);
}


}


return list;


}


/**
* 查询订单信息
*/


public ArrayList<MachinesMaintain> executeMaintainQuery(String sql) {
this.methodName = "executeMaintainQuery";
initConfig(sql);


if (envelope.bodyIn instanceof SoapFault) {
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("", str);
} else {


SoapObject result = (SoapObject) envelope.bodyIn;


if (result != null) {
for (int i = 0; i < result.getPropertyCount(); i++) {


SoapObject child = (SoapObject) result.getProperty(i);
// System.out.println(child);
MachinesMaintain order = new MachinesMaintain();


order.setId(Integer.parseInt(child.getProperty("id")
.toString()));
if ("".equals(child.getProperty("roomCode").toString()
.trim())) {


order.setRoomCode(" ");
} else {
order.setRoomCode(child.getProperty("roomCode")
.toString().trim());


}


if ("".equals(child.getProperty("groupCode").toString()
.trim())) {


order.setGroupCode(" ");
} else {
order.setGroupCode(child.getProperty("groupCode")
.toString().trim());


}


if ("".equals(child.getProperty("machCode").toString()
.trim())) {


order.setMachCode(0);
} else {


order.setMachCode(Integer.parseInt(child.getProperty(
"machCode").toString()));
}


if ("".equals(child.getProperty("state").toString().trim())) {


order.setState(-1);
} else {
order.setState(Integer.parseInt(child.getProperty(
"state").toString()));


}


if ("".equals(child.getProperty("stopReason").toString()
.trim())) {


order.setStopReason(" ");
} else {
order.setStopReason(child.getProperty("stopReason")
.toString().trim());


}


if ("".equals(child.getProperty("dateStartShift")
.toString().trim())) {


order.setDateStartShift("");
} else {
order.setDateStartShift(child
.getProperty("dateStartShift").toString()
.trim());


}


if ("".equals(child.getProperty("serviceMan").toString()
.trim())) {


order.setServiceMan("");
} else {
order.setServiceMan(child.getProperty("serviceMan")
.toString().trim());


}


if ("".equals(child.getProperty("receiveDate").toString()
.trim())) {


order.setReceiveDate("");
} else {
order.setReceiveDate(child.getProperty("receiveDate")
.toString().trim());


}


if ("".equals(child.getProperty("okDate").toString().trim())) {


order.setOkDate("");
} else {
order.setOkDate(child.getProperty("okDate").toString()
.trim());


}


order.setReceiveFlag(Integer.parseInt(child.getProperty(
"receiveFlag").toString()));
order.setOkFlag(Integer.parseInt(child
.getProperty("okFlag").toString()));


System.out.println(order.getId());


maintainlist.add(order);
}


return maintainlist;
}
return null;


}
return null;
}


public boolean isExistUser(String sql) {
this.setMethodName("isExistUser");
initConfig(sql);
Object soapObject = null;


if (envelope.bodyIn instanceof SoapFault) {
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("", str);
} else {


try {
soapObject = (Object) envelope.getResponse();
} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}
return Boolean.parseBoolean(soapObject.toString());
}


public boolean insertUser(String sql) {
this.setMethodName("insertUser");
initConfig(sql);
Object soapObject = null;


if (envelope.bodyIn instanceof SoapFault) {
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("", str);
} else {


try {
soapObject = (Object) envelope.getResponse();
} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}
return Boolean.parseBoolean(soapObject.toString());
}


public boolean updateUser(String sql) {
this.setMethodName("updateUser");
initConfig(sql);
Object soapObject = null;


if (envelope.bodyIn instanceof SoapFault) {
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("", str);
} else {


try {
soapObject = (Object) envelope.getResponse();
} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


}
return Boolean.parseBoolean(soapObject.toString());
}


public User queryUser(String sql) {


this.setMethodName("queryUser");
initConfig(sql);


User user = new User();


if (envelope.bodyIn instanceof SoapFault) {
String str = ((SoapFault) envelope.bodyIn).faultstring;
Log.i("", str);


} else {
SoapObject result = (SoapObject) envelope.bodyIn;
System.out.println(result);


if (result != null) {


SoapObject child = (SoapObject) result.getProperty(0);


// System.out.println("child--" + child);


if (child.getProperty("plantCode") == null) {


user.setPlantCode(" ");
} else {
user.setPlantCode(child.getProperty("plantCode").toString());
}


if (child.getProperty("roomCode") == null) {


user.setRoomCode(" ");
} else {
user.setRoomCode(child.getProperty("roomCode").toString());
}


if (child.getProperty("groupCode") == null) {


user.setGroupCode(" ");
} else {
user.setGroupCode(child.getProperty("groupCode").toString());
}


if (child.getProperty("userName") == null) {


user.setUserName("");
} else {
user.setUserName(child.getProperty("userName").toString());


}


if (child.getProperty("userPhoneNumber") == null) {


user.setUserPhoneNumber("");
} else {
user.setUserPhoneNumber(child
.getProperty("userPhoneNumber").toString());


}


if (child.getProperty("inDate") == null) {


user.setInDate("");
} else {
user.setInDate(child.getProperty("inDate").toString());


}


return user;


}
}


return null;


}


}







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值