You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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);
        }
    }
}

必须注意的几个坑

  1. 网络权限:别忘了在AndroidManifest.xml里添加网络权限,否则请求会失败:
<uses-permission android:name="android.permission.INTERNET" />
  1. 命名空间不能错:你之前把NAMESPACE写成了http://tempuri.org/GetAssets,这是错误的,正确的应该是服务的根命名空间http://tempuri.org/,SOAP_ACTION才是命名空间加方法名。
  2. 不能在主线程发请求:Android从4.0开始就禁止在主线程执行网络操作,必须用异步任务、协程或者RxJava来处理。
  3. 复杂响应解析:如果服务端返回的是复杂对象(比如资产列表),需要用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);
}
  1. 参数大小写敏感:添加请求参数时,参数名要和服务端定义的完全一致(包括大小写),否则服务端会识别不到参数。

内容的提问来源于stack exchange,提问作者Shoaib Anwar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:32:07