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

基于Apache HttpClient5的Spring SOAP WebService客户端示例求助

基于Apache HttpClient5的Spring SOAP WebService客户端实现

1. 依赖配置(Maven)

在pom.xml中引入必要依赖,排除Spring默认的HttpClient4.x依赖,替换为HttpClient5:

<dependencies>
    <!-- Spring Web Services核心依赖 -->
    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-core</artifactId>
        <version>4.0.0</version>
        <!-- 排除HttpClient4依赖避免冲突 -->
        <exclusions>
            <exclusion>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- Apache HttpClient5依赖 -->
    <dependency>
        <groupId>org.apache.httpcomponents.client5</groupId>
        <artifactId>httpclient5</artifactId>
        <version>5.2.3</version>
    </dependency>

    <!-- Spring Boot基础依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>3.0.1</version>
    </dependency>
</dependencies>

2. 自定义HttpClient5消息发送器

Spring WS 4.0.0暂未提供官方的HttpClient5适配类,需自定义实现WebServiceMessageSender封装HttpClient5请求逻辑:

import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.InputStreamEntity;
import org.springframework.ws.transport.WebServiceConnection;
import org.springframework.ws.transport.http.AbstractHttpWebServiceMessageSender;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;

public class HttpComponents5MessageSender extends AbstractHttpWebServiceMessageSender {

    private final HttpClient httpClient;

    public HttpComponents5MessageSender(HttpClient httpClient) {
        this.httpClient = httpClient;
    }

    @Override
    protected WebServiceConnection createConnection(URI uri) throws IOException {
        HttpPost httpPost = new HttpPost(uri);
        return new HttpComponents5Connection(httpPost, httpClient);
    }

    private static class HttpComponents5Connection extends org.springframework.ws.transport.http.HttpComponentsConnection {

        private final HttpPost httpPost;
        private final HttpClient httpClient;
        private org.apache.hc.core5.http.HttpResponse httpResponse;

        public HttpComponents5Connection(HttpPost httpPost, HttpClient httpClient) {
            super(httpPost);
            this.httpPost = httpPost;
            this.httpClient = httpClient;
        }

        @Override
        protected void onSendBeforeWrite(org.springframework.ws.WebServiceMessage message) throws IOException {
            httpPost.setHeader("Content-Type", "text/xml");
        }

        @Override
        protected OutputStream getRequestOutputStream() throws IOException {
            return new OutputStream() {
                private final ByteArrayOutputStream baos = new ByteArrayOutputStream();

                @Override
                public void write(int b) throws IOException {
                    baos.write(b);
                }

                @Override
                public void flush() throws IOException {
                    baos.flush();
                    InputStreamEntity entity = new InputStreamEntity(new ByteArrayInputStream(baos.toByteArray()));
                    httpPost.setEntity(entity);
                }
            };
        }

        @Override
        protected org.apache.hc.core5.http.HttpResponse execute(org.apache.hc.client5.http.classic.HttpUriRequest request) throws IOException {
            this.httpResponse = httpClient.execute(httpPost);
            return this.httpResponse;
        }

        @Override
        protected InputStream getResponseInputStream() throws IOException {
            HttpEntity entity = httpResponse.getEntity();
            return entity.getContent();
        }

        @Override
        public void close() throws IOException {
            try {
                if (httpResponse != null) {
                    EntityUtils.consume(httpResponse.getEntity());
                }
            } finally {
                super.close();
            }
        }
    }
}

3. 配置WebServiceTemplate及超时参数

通过配置类创建HttpClient5实例并设置超时,同时初始化WebServiceTemplate:

import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.HttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.util.Timeout;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.transport.WebServiceMessageSender;

@Configuration
public class SoapClientConfig {

    // 配置HttpClient5,设置各类超时参数
    @Bean
    public HttpClient httpClient() {
        // 连接超时:建立TCP连接的最大等待时间
        ConnectionConfig connectionConfig = ConnectionConfig.custom()
                .setConnectTimeout(Timeout.ofSeconds(5))
                .build();

        // 请求超时:从连接池获取连接+读取响应的总超时
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(Timeout.ofSeconds(3))
                .setResponseTimeout(Timeout.ofSeconds(10))
                .build();

        return HttpClientBuilder.create()
                .setDefaultConnectionConfig(connectionConfig)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

    // 注册自定义HttpClient5消息发送器
    @Bean
    public WebServiceMessageSender webServiceMessageSender(HttpClient httpClient) {
        return new HttpComponents5MessageSender(httpClient);
    }

    // 初始化WebServiceTemplate
    @Bean
    public WebServiceTemplate webServiceTemplate(WebServiceMessageSender messageSender) {
        WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
        webServiceTemplate.setMessageSenders(new WebServiceMessageSender[]{messageSender});
        // 可设置默认SOAP服务地址
        // webServiceTemplate.setDefaultUri("http://your-soap-service-endpoint");
        return webServiceTemplate;
    }
}

4. SOAP客户端调用示例

注入WebServiceTemplate即可发起SOAP请求:

import org.springframework.stereotype.Component;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.soap.client.core.SoapActionCallback;

@Component
public class SoapClient {

    private final WebServiceTemplate webServiceTemplate;

    public SoapClient(WebServiceTemplate webServiceTemplate) {
        this.webServiceTemplate = webServiceTemplate;
    }

    public <T> T callSoapService(String serviceUrl, Object request, Class<T> responseType) {
        // 根据实际服务要求设置SOAP Action
        SoapActionCallback callback = new SoapActionCallback("http://your-soap-action-uri");
        return (T) webServiceTemplate.marshalSendAndReceive(serviceUrl, request, callback);
    }
}

参考文档(中文翻译)

  • Apache HttpClient 5.2.x 迁移指南
  • Spring Boot实现SOAP WebService客户端
  • Spring WebServiceTemplate如何设置超时

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:20:22