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

Axis2客户端调用Web服务时出现HttpClient类型转换异常

Axis2客户端HttpClient类型转换异常及解决办法

异常现象

调用第三方Web服务时出现类型转换异常:

java.lang.ClassCastException: class org.apache.http.impl.client.InternalHttpClient cannot be cast to class org.apache.commons.httpclient.HttpClient (org.apache.http.impl.client.InternalHttpClient and org.apache.commons.httpclient.HttpClient are in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @674c583e)
        at org.apache.axis2.transport.http.AbstractHTTPSender.getHttpClient(AbstractHTTPSender.java:529)
        at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:157)
        at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:75)
        at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:404)
        at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:231)
        at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:443)
        at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:406)
        at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
        at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)

问题代码

设置CACHED_HTTP_CLIENT属性的代码:

MyStub stub = new MyStub() ; 

stub._getServiceClient().getOptions().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, customHttpClient);
stub._getServiceClient().getServiceContext()
        .setProperty(HTTPConstants.CACHED_HTTP_CLIENT, customHttpClient);

异常触发点在AbstractHttpSender的以下代码行:

HttpClient httpClient = (HttpClient) msgContext.getProperty(
        HTTPConstants.CACHED_HTTP_CLIENT);

问题核心

Axis2默认使用的CommonsHTTPTransportSender依赖org.apache.commons.httpclient.HttpClient(旧版commons-httpclient包),而你传入的customHttpClient是org.apache.http.client.HttpClient(新版Apache HttpComponents的httpclient包,4.x及以后版本)。这两个是完全独立的类,无继承或实现关系,因此触发类型转换异常。

解决方案

方案1:改用旧版commons-httpclient创建实例

直接创建符合Axis2默认要求的旧版HttpClient实例:

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;

// 创建线程安全的HttpClient实例
MultiThreadedHttpConnectionManager connManager = new MultiThreadedHttpConnectionManager();
HttpClient customHttpClient = new HttpClient(connManager);

// 配置连接超时、读取超时等参数
customHttpClient.getParams().setConnectionTimeout(5000);
customHttpClient.getParams().setSoTimeout(10000);

// 设置到Stub中
MyStub stub = new MyStub();
stub._getServiceClient().getOptions().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, customHttpClient);
stub._getServiceClient().getServiceContext().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, customHttpClient);

方案2:更换Axis2传输发送器为HttpComponentsTransportSender

若希望继续使用新版HttpClient,可切换到支持新版HttpComponents的传输发送器:

方式1:通过配置文件修改

  1. 确保项目引入axis2-transport-http依赖包(包含HttpComponentsTransportSender)
  2. 修改Axis2配置文件axis2.xml(web项目放WEB-INF/conf,客户端放classpath根目录):
<!-- 注释原有的CommonsHTTPTransportSender -->
<!-- <transportSender name="http" class="org.apache.axis2.transport.http.CommonsHTTPTransportSender"> -->
<!--     <parameter name="PROTOCOL">HTTP/1.1</parameter> -->
<!--     <parameter name="Transfer-Encoding">chunked</parameter> -->
<!-- </transportSender> -->

<!-- 添加支持新版HttpClient的传输发送器 -->
<transportSender name="http" class="org.apache.axis2.transport.http.HttpComponentsTransportSender">
    <parameter name="PROTOCOL">HTTP/1.1</parameter>
    <parameter name="Transfer-Encoding">chunked</parameter>
</transportSender>
  1. 直接传入新版HttpClient实例:
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.config.RequestConfig;

// 创建带超时配置的新版HttpClient
RequestConfig requestConfig = RequestConfig.custom()
        .setConnectTimeout(5000)
        .setSocketTimeout(10000)
        .build();
CloseableHttpClient customHttpClient = HttpClients.custom()
        .setDefaultRequestConfig(requestConfig)
        .build();

// 设置到Stub中
MyStub stub = new MyStub();
stub._getServiceClient().getOptions().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, customHttpClient);
stub._getServiceClient().getServiceContext().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, customHttpClient);

方式2:通过代码动态设置传输发送器

无需修改配置文件,直接在代码中替换传输发送器:

import org.apache.axis2.transport.http.HttpComponentsTransportSender;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

MyStub stub = new MyStub();
ServiceClient serviceClient = stub._getServiceClient();

// 移除默认的CommonsHTTPTransportSender
serviceClient.removeTransportSender("http");

// 添加HttpComponentsTransportSender
HttpComponentsTransportSender sender = new HttpComponentsTransportSender();
serviceClient.addTransportSender("http", sender);

// 设置新版HttpClient
CloseableHttpClient customHttpClient = HttpClients.createDefault();
serviceClient.getOptions().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, customHttpClient);
serviceClient.getServiceContext().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, customHttpClient);

方案3:自定义适配器(不推荐)

自行编写适配器类,将新版HttpClient适配为旧版org.apache.commons.httpclient.HttpClient接口的实现。但该方式需实现旧版接口所有方法,开发成本高且易引入兼容性问题,不建议采用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 18:54:53