KSOAP2 是第三方开发的专门用于在移动设备调用WebService的类库。使用 KSOAP2 调用 WebService 可分为6步来完成,其中主要使用了
SoapObject 对象来指定了要调用的方法,然后通过 HttpTransportSE 对象的call方法来调用WebService的方法,最后通过 getResponse
方法返回结果。读者可以通过本文提 供的完整示例来体会使用KSOAP2调用WebService的完整过程。在最后还介绍了如何通过异步调用
WebService 的方式来防止因服务端故障 或其他原因导致的UI组件阻塞。
使用KSOAP2调用WebService:
// 1. 指定WebService的命名空间和调用的方法名
SoapObject request = new SoapObject("http://service", "getName");
// 2. 设置调用方法的参数值
request.addProperty("param1", "value1");
request.addProperty("param2", "value2");
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
// 3. 生成调用WebService方法的SOAP请求信息。该信息由SoapSerializationEnvelope对象描述
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = request;
常量SoapEnvelope.VER10:对应于SOAP 1.0规范
常量SoapEnvelope.VER11:对应于SOAP 1.1规范
常量SoapEnvelope.VER12:对应于SOAP 1.2规范
// 4. 创建HttpTransportSE对象。
HttpTransportSE ht = new HttpTransportSE("http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl");
// HttpTransport 是一个强大的辅助类,来完成 Http-call transport process,它封装了网络请求的一切,你完全不用考虑序列化消息。
// 我们通过设置它的debug属性为true来打开调试信息。
// HttpTransport tx = new HttpTransport(serviceURL);
// ht.debug = true;
// 5. 使用call方法调用WebService方法,代码如下:
ht.call(null, envelope);
// 由于 HttpTransport 类实际上是调用了 HttpConnection 作网络连接,所以必须另起一个线程来专门做kSOAP工作,否则会堵塞操作。
// 6. 使用getResponse方法获得WebService方法的返回结果,代码如下:
SoapObject soapObject = (SoapObject) envelope.getResponse();
import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class Main extends Activity implements OnClickListener { @Override public void onClick(View view) { EditText etProductName = (EditText)findViewById(R.id.etProductName); TextView tvResult = (TextView)findViewById(R.id.tvResult); // WSDL文档的URL,192.168.17.156为PC的ID地址 String serviceUrl = "http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl"; // 定义调用的WebService方法名 String methodName = "getProduct"; // 第1步:创建 SoapObject 对象,并指定 WebService 的命名空间和调用的方法名 SoapObject request = new SoapObject("http://service", methodName); // 第2步:设置WebService方法的参数 request.addProperty("productName", etProductName.getText().toString()); // 第3步:创建SoapSerializationEnvelope对象,并指定WebService的版本 SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); // 设置bodyOut属性 envelope.bodyOut = request; // 第4步:创建HttpTransportSE对象,并指定WSDL文档的URL HttpTransportSE ht = new HttpTransportSE(serviceUrl); try { // 第5步:调用WebService ht.call(null, envelope); if (envelope.getResponse() != null) { // 第6步:使用 getResponse 方法获得WebService方法的返回结果 SoapObject soapObject = (SoapObject) envelope.getResponse(); // 通过 getProperty 方法获得 Product 对象的属性值 String result = "产品名称:" + soapObject.getProperty("name") + "\n"; result += "产品数量:" + soapObject.getProperty("productNumber") + "\n"; result += "产品价格:" + soapObject.getProperty("price"); tvResult.setText(result); } else { tvResult.setText("无此产品."); } } catch (Exception e) { } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btnSearch = (Button) findViewById(R.id.btnSearch); btnSearch.setOnClickListener(this); } }
// 异步处理结果
import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class Main extends Activity implements OnClickListener { private EditText etProductName; private TextView tvResult; class WSAsyncTask extends AsyncTask { String result = ""; @Override protected Object doInBackground(Object... params) { try { String serviceUrl = "http://192.168.17.156:8080/axis2/services/SearchProductService?wsdl"; String methodName = "getProduct"; SoapObject request = new SoapObject("http://service", methodName); request.addProperty("productName", etProductName.getText().toString()); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope( SoapEnvelope.VER11); envelope.bodyOut = request; HttpTransportSE ht = new HttpTransportSE(serviceUrl); ht.call(null, envelope); if (envelope.getResponse() != null) { SoapObject soapObject = (SoapObject) envelope.getResponse(); result = "产品名称:" + soapObject.getProperty("name") + "\n"; result += "产品数量:" + soapObject.getProperty("productNumber") + "\n"; result += "产品价格:" + soapObject.getProperty("price"); } else { result = "无此产品."; } } catch (Exception e) { result = "调用WebService错误."; } // 必须使用post方法更新UI组件 tvResult.post(new Runnable() { @Override public void run() { tvResult.setText(result); } }); return null; } } @Override public void onClick(View view) { // 异步执行调用WebService的任务 new WSAsyncTask().execute(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button btnSearch = (Button) findViewById(R.id.btnSearch); btnSearch.setOnClickListener(this); etProductName = (EditText) findViewById(R.id.etProductName); tvResult = (TextView) findViewById(R.id.tvResult); } }