如何在Android中使用SOAP Web服务?集成及代码问题求助
Android中用kSOAP集成SOAP Web服务的完整指南
我看到你已经开始尝试用kSOAP在Android里集成SOAP服务了,不过代码好像没写完,而且有个容易踩的小细节(命名空间写错了),先给你理清楚SOAP的核心逻辑,再把完整的实现代码补全,顺便说下大家常遇到的问题。
先快速搞懂SOAP的核心逻辑
SOAP本质是用XML包裹请求数据,通过HTTP发送给服务端,服务端处理后再返回XML格式的响应。你代码里的几个关键参数一定要搞对:
- URL:SOAP服务的端点地址(就是你要请求的那个asmx文件地址)
- NAMESPACE:服务的命名空间,一般是服务端定义的根路径(不是方法路径!你之前写的就错了)
- SOAP_ACTION:告诉服务端要调用的具体方法,格式是「命名空间+方法名」
- METHOD_NAME:你要调用的服务端方法名
完整实现代码(含异步请求)
首先确保你已经在build.gradle里加了kSOAP的依赖:
implementation 'com.google.code.ksoap2-android:ksoap2-android:3.6.4'
然后补全你的Activity代码(注意网络请求不能在主线程,这里用AsyncTask做异步处理):
public class SOAP extends AppCompatActivity { // 修正后的命名空间:是根路径,不是方法路径 private static final String URL = "http://www.getrixi.com/GoTukxiWebServices/TukxiService.asmx"; private static final String NAMESPACE = "http://tempuri.org/"; private static final String SOAP_ACTION = "http://tempuri.org/GetAssets"; private static final String METHOD_NAME = "GetAssets"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_soap); // 启动异步任务执行SOAP请求 new CallSOAPTask().execute(); } // 异步任务类,专门处理网络请求 private class CallSOAPTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... voids) { // 1. 创建SOAP请求对象,指定命名空间和方法名 SoapObject soapRequest = new SoapObject(NAMESPACE, METHOD_NAME); // 如果GetAssets方法需要参数,在这里添加(参数名要和服务端完全一致) // 示例:soapRequest.addProperty("AssetType", "Car"); // 2. 创建SOAP信封,指定SOAP版本(这里用SOAP 1.1,对应.NET的ASMX服务) SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(soapRequest); // 针对.NET的ASMX服务,必须设置这个属性为true,否则解析会失败 envelope.dotNet = true; // 3. 创建HTTP传输对象,发送请求 HttpTransportSE httpTransport = new HttpTransportSE(URL); try { // 调用服务 httpTransport.call(SOAP_ACTION, envelope); // 获取响应(如果是简单字符串用SoapPrimitive,复杂对象用SoapObject) SoapPrimitive response = (SoapPrimitive) envelope.getResponse(); return "请求成功:" + response.toString(); } catch (Exception e) { e.printStackTrace(); return "请求失败:" + e.getMessage(); } } @Override protected void onPostExecute(String result) { super.onPostExecute(result); // 在这里处理返回结果,比如显示到界面上 // 示例:TextView resultTv = findViewById(R.id.tv_result); // resultTv.setText(result); Log.d("SOAP_RESULT", result); } } }
必须注意的几个坑
- 网络权限:别忘了在
AndroidManifest.xml里添加网络权限,否则请求会失败:
<uses-permission android:name="android.permission.INTERNET" />
- 命名空间不能错:你之前把NAMESPACE写成了
http://tempuri.org/GetAssets,这是错误的,正确的应该是服务的根命名空间http://tempuri.org/,SOAP_ACTION才是命名空间加方法名。 - 不能在主线程发请求:Android从4.0开始就禁止在主线程执行网络操作,必须用异步任务、协程或者RxJava来处理。
- 复杂响应解析:如果服务端返回的是复杂对象(比如资产列表),需要用
SoapObject来解析:
SoapObject response = (SoapObject) envelope.getResponse(); // 遍历响应里的属性 for (int i = 0; i < response.getPropertyCount(); i++) { String propName = response.getPropertyName(i); Object propValue = response.getProperty(i); Log.d("SOAP_DATA", propName + ": " + propValue); }
- 参数大小写敏感:添加请求参数时,参数名要和服务端定义的完全一致(包括大小写),否则服务端会识别不到参数。
内容的提问来源于stack exchange,提问作者Shoaib Anwar
相关产品推荐
相关产品推荐

