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

Android Studio中使用EasyWsdl为SOAP请求添加请求头失败求助

解决EasyWSDL生成类添加SOAP请求HTTP头的问题

我懂你现在的困境——折腾了OkHTTP、kSoap2,好不容易换成EasyWSDL生成的类能发SOAP请求了,结果卡在加请求头这一步,确实挺烦人的。你用HeaderProperty的思路是对的,但EasyWSDL封装了底层的kSoap2逻辑,直接这么加可能没走对路子,我给你几个可行的方案:

1. 先检查EasyWSDL生成的客户端类有没有内置方法

很多时候EasyWSDL生成的代码会自带设置请求头的方法,比如setHeaders(List<HeaderProperty>)或者addHeader(HeaderProperty)。你可以先翻一下生成的客户端类的代码,比如找类似这样的方法:

public void setHeaders(List<HeaderProperty> headers) {
    this.transport.setHeaders(headers);
}

如果有的话,直接创建HeaderProperty列表传进去就行,不用绕弯路:

// 构建Authorization头
String credentials = "your_username:your_password";
String encodedAuth = android.util.Base64.encodeToString(credentials.getBytes(), android.util.Base64.NO_WRAP);
HeaderProperty authHeader = new HeaderProperty("Authorization", "Basic " + encodedAuth);

// 添加到列表
List<HeaderProperty> headers = new ArrayList<>();
headers.add(authHeader);

// 调用生成类的内置方法
YourGeneratedSoapClient client = new YourGeneratedSoapClient();
client.setHeaders(headers);

// 然后正常调用接口方法就行
client.yourSoapMethod(yourRequest);

2. 直接操作底层的kSoap2传输对象

如果生成的类没暴露设置头的方法,那就得拿到底层的HttpTransportSE(kSoap2的核心传输类),在调用请求的时候传入头列表。

首先找到生成类里负责发送请求的代码,通常会有类似这样的逻辑:

private HttpTransportSE transport;
private SoapSerializationEnvelope envelope;

public YourResponse yourSoapMethod(YourRequest request) throws Exception {
    envelope.setOutputSoapObject(request);
    transport.call(SOAP_ACTION, envelope);
    return (YourResponse) envelope.getResponse();
}

你可以修改这个方法,让它接受List<HeaderProperty>参数,然后在call方法里传入:

// 修改后的方法
public YourResponse yourSoapMethod(YourRequest request, List<HeaderProperty> headers) throws Exception {
    envelope.setOutputSoapObject(request);
    // 第三个参数就是请求头列表
    transport.call(SOAP_ACTION, envelope, headers);
    return (YourResponse) envelope.getResponse();
}

然后调用的时候传入你的头列表就行。如果生成的类把transport设成了private,你也可以用反射来获取它(虽然有点hack,但应急能用):

YourGeneratedSoapClient client = new YourGeneratedSoapClient();

// 反射获取private的transport字段
Field transportField = YourGeneratedSoapClient.class.getDeclaredField("transport");
transportField.setAccessible(true);
HttpTransportSE transport = (HttpTransportSE) transportField.get(client);

// 构建请求头
List<HeaderProperty> headers = new ArrayList<>();
String encodedAuth = android.util.Base64.encodeToString("user:pass".getBytes(), android.util.Base64.NO_WRAP);
headers.add(new HeaderProperty("Authorization", "Basic " + encodedAuth));

// 手动调用传输对象的call方法
transport.call(SOAP_ACTION, client.envelope, headers);
YourResponse response = (YourResponse) client.envelope.getResponse();

3. 注意Base64编码的坑

这里要特别提醒:别用kSoap2自带的org.kobjects.base64.Base64,用Android系统自带的android.util.Base64,并且一定要加Base64.NO_WRAP参数——很多服务器会因为编码后的字符串带换行符而拒绝解析Authorization头,这个细节很容易踩坑。

4. 用OkHTTP拦截器全局加头(如果底层用OkHTTP)

如果你的EasyWSDL生成的代码用了OkHTTP作为传输层(比如用了OkHttpTransport),那用拦截器全局加请求头会更灵活,不用每次调用都传:

// 创建带拦截器的OkHttpClient
OkHttpClient okHttpClient = new OkHttpClient.Builder()
    .addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request originalRequest = chain.request();
            // 添加上Authorization头
            Request modifiedRequest = originalRequest.newBuilder()
                .header("Authorization", "Basic " + yourEncodedAuth)
                .build();
            return chain.proceed(modifiedRequest);
        }
    })
    .build();

// 把这个client传给EasyWSDL生成的传输对象(如果生成类支持的话)
YourGeneratedSoapClient client = new YourGeneratedSoapClient();
client.setOkHttpClient(okHttpClient);

最后几个小提醒

  • 区分清楚HTTP请求头和SOAP消息头:你用HeaderProperty加的是HTTP请求头,如果要加SOAP消息里的<Header>节点,那得往SoapEnvelope里加SoapHeader对象,别搞混了。
  • 如果服务器返回401,先检查用户名密码是否正确,编码后的字符串有没有空格(Basic后面必须加空格)。
  • 有些SOAP服务还要求SOAPAction头,确保生成的代码已经正确设置了这个头。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:14:32