下面是使用ksoap2调用webservice的一个例子:
package com.test;
import java.io.UnsupportedEncodingException;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class TestWebserviceActivity extends Activity {
/** Called when the activity is first created. */
private Button okButton;
//WebService 的命名空间
private static final String NAMESPACE = "http://WebXml.com.cn/";
// WebService地址 服务网址
private static String URL = "http://www.webxml.com.cn/webservices/weatherwebservice.asmx";
//要调用的方法
private static final String METHOD_NAME = "getWeatherbyCityName";
//rest资源,SOAPAction
private static String SOAP_ACTION = "http://WebXml.com.cn/getWeatherbyCityName";
private String weatherToday;
private SoapObject detail;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
okButton = (Button) this.findViewById(R.id.btn_Search);
okButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
String city = "北京";
getWeather(city);
}
});
}
public void getWeather(String cityName) {
try {
/**
* SoapObject构造函数的两个参数含义为:
* serviceNamespace -- 你的webservice的命名空间,既可以是
* http://localhost:8088/flickrBuddy/services/Buddycast这样的,也可以是
* urn:PI/DevCentral/SoapService这样的;
* methodName -- 你要调用方法的名字
*/
SoapObject rpc = new SoapObject(NAMESPACE, METHOD_NAME);
/**
* 设置调用方法的参数值,如果没有参数,可以省略
* 要注意的是,addProperty方法的第1个参数虽然表示调用方法的参数名,
* 但该参数值并不一定与服务端的WebService类中的方法参数名一致,只要设置参数的顺序一致即可。
*/
rpc.addProperty("theCityName", cityName);
/**
* 创建SoapSerializationEnvelope对象时需要通过SoapSerializationEnvelope类的构造方法设置SOAP协议的版本号。
* 该版本号需要根据服务端WebService的版本号设置。
* 要点:
* 你可以通过SoapSerializationEnvelope或者SoapEnvelope的构造函数来指明你要用SOAP的哪一个规范,可以是以下几种之一:
* 常量SoapEnvelope.VER10:对应于SOAP 1.0规范
* 常量SoapEnvelope.VER11:对应于SOAP 1.1规范
* 常量SoapEnvelope.VER12:对应于SOAP 1.2规范
* 这样,无论要调用的webservice采用了哪一个SOAP规范,你都可以轻松应对。
*/
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
/**
* 发送请求
* 设置SOAPSoapSerializationEnvelope类的bodyOut属性,
* 该属性的值就是在第一步创建的SoapObject对象。
*/
envelope.bodyOut = rpc;
/**
* 这里如果设置为TRUE,那么在服务器端将获取不到参数值(如:将这些数据插入到数据库中的话)
*/
envelope.dotNet = false;
envelope.setOutputSoapObject(rpc);
/**
* HttpTransportSE 构造函数参数含义为:
* serviceURL -- 要投递SOAP数据的目标地址,如:
* http://soap.amazon.com/onca/soap3
* HttpTransportSE是一个强大的辅助类,来完成Http-call transport process,它封装了网络
* 请求的一切,你完全不用考虑序列化消息。
*/
HttpTransportSE ht = new HttpTransportSE(URL);
/**
* AndroidHttpTransport是要过期的类,不推荐使用
*/
//AndroidHttpTransport ht = new AndroidHttpTransport(URL);
/**
* 通过设置debug属性为true来打开调试信息。
*/
ht.debug = true;
/**
* HttpTransportSE.call()自己就能够发送请求给服务器、接收服务器响应并序列化SOAP消息。
* 两个参数含义:
* soapAction - SOAP规范定义了一个名为SOAPAction的新HTTP标头,所有SOAP HTTP 请求(即使是空的)
* 都必须包含该标头。SOAPAction标头旨在表明该消息的意图。通常可以置此参数为null,这样
* HttpTransportSE就会设置HTTP标头SOAPAction为空字符串
* Envelope - 就是之前我们构造好的SoapSerializationEnvelop或SoapEnvelope对象。
*
* 注意:
* 对于HttpTransportSE的处理上,kSOAP2和kSOAP1.2的写法不一样:
* 1)对于kSOAP1.2 HttpTransportSE的构造函数是HttpTransportSE(String url, String soapAction),
* 第二个参数soapAction可以是要调用的webservice方法名。
* 2)kSOAP2,构造函数是HttpTransportSE(String url)。kSOAP2相当于把webservice方法名分离出来,完全交给
* SoapObject去封装,而HttpTransportSE仅仅负责把SoapEnvelope发出去并接收响应
*/
ht.call(SOAP_ACTION, envelope);
//ht.call(null, envelope);
/**
* 获得WebService方法的返回结果
* 有两种方法:
* 1、使用getResponse方法获得返回数据。
* 2、使用 bodyIn 及 getProperty。
*/
//SoapObject result = (SoapObject)envelope.bodyIn;
//detail = (SoapObject) result.getProperty("getWeatherbyCityNameResult");
detail =(SoapObject) envelope.getResponse();
parseWeather(detail);
return;
} catch (Exception e) {
e.printStackTrace();
}
}
private void parseWeather(SoapObject detail)
throws UnsupportedEncodingException {
/**
* 对于webservice方法返回String类型的情况,还用不着开发者做序列化(Serialization)定制工作
* 要点:
* kSOAP 1.X/2.0可以自动把四种SOAP类型映射为Java类型
* SOAP type java type
* xsd:int java.lang.Integer
* xsd:long java.lang.Long
* xsd:string java.lang.String
* xsd:boolean java.lang.Boolean
* 除此之外,都需要开发者自己做类型映射。
*/
String date = detail.getProperty(6).toString();
weatherToday = "今天:" + date.split(" ")[0];
weatherToday = weatherToday + "\n天气:" + date.split(" ")[1];
weatherToday = weatherToday + "\n气温:"
+ detail.getProperty(5).toString();
weatherToday = weatherToday + "\n风力:"
+ detail.getProperty(7).toString() + "\n";
System.out.println("weatherToday is " + weatherToday);
Toast.makeText(this, weatherToday, Toast.LENGTH_LONG).show();
}
}