基于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
相关产品推荐
相关产品推荐

