简单易用的httpclient封装
可以发送HTTP和HTTPS请求。HTTPS既可以绕过证书检查,也可以不绕过证书检查。
使用httpclient-4.5.1版本。
参考文章:
轻松把玩HttpClient之配置ssl,采用设置信任自签名证书实现https
spring集成httpclient配置
定义HttpService接口
遵循代码的设计原则,面向接口编程,这里自定义一些常用的http方法。
package com.light.httpclient.http.inf;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import org.apache.http.Header;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import com.light.httpclient.http.HttpResult;
public interface HttpService {
/**
*
* 设置请求客户端实例
*
* @param httpclient
*/
void setCloseableHttpClient(CloseableHttpClient closeableHttpClient);
/**
*
* 向服务端发送请求的公共方法
*
* @param method
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult connect(HttpRequestBase method) throws ParseException, ClientProtocolException, IOException;
/**
*
* @param url
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doGet(String url) throws ParseException, ClientProtocolException, IOException;
/**
*
* @param url
* @param params
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doGet(String url, Map<String, String> params)
throws ParseException, ClientProtocolException, IOException, URISyntaxException;
/**
*
* @param url
* @param params
* @param headers
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doGet(String url, Map<String, String> params, List<Header> headers)
throws ParseException, ClientProtocolException, IOException, URISyntaxException;
/**
*
* @param url
* 请求地址
* @param json
* JSON格式的请求参数
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doPost(String url, String json) throws ParseException, ClientProtocolException, IOException;
/**
*
* @param url
* @param json
* @param headers
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doPost(String url, String json, List<Header> headers)
throws ParseException, ClientProtocolException, IOException;
/**
*
* @param url
* @param parameter
* @param contentType
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doPost(String url, String parameter, ContentType contentType)
throws ParseException, ClientProtocolException, IOException;
/**
*
* @param url
* @param parameter
* @param headers
* @param contentType
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doPost(String url, String parameter, List<Header> headers, ContentType contentType)
throws ParseException, ClientProtocolException, IOException;
/**
*
* @param url
* @param params
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doPost(String url, Map<String, String> params)
throws ParseException, ClientProtocolException, IOException;
/**
*
* @param url
* @param params
* @param headers
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doPost(String url, Map<String, String> params, List<Header> headers)
throws ParseException, ClientProtocolException, IOException;
/**
*
* @param url
* @param params
* @param headers
* @param charset
* 取值请参考 {@link org.apache.http.Consts}
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
HttpResult doPost(String url, Map<String, String> params, List<Header> headers, Charset charset)
throws ParseException, ClientProtocolException, IOException;
}
定义抽象类AbstractHttpConnect
这里采用缺省适配器模式,如果抽象类的方法不能满足需求可以在子类中重写。
package com.light.httpclient.http.impl;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.light.httpclient.http.HttpResult;
import com.light.httpclient.http.inf.HttpService;
public abstract class AbstractHttpConnect implements HttpService {
protected CloseableHttpClient closeableHttpClient;
public abstract void setCloseableHttpClient(CloseableHttpClient closeableHttpClient);
/**
*
* 请求服务端方法
*
* @param method
* 请求方式:GET POST DELETE PUT
* @return
* @throws ParseException
* @throws ClientProtocolException
* @throws IOException
*/
@Override
public HttpResult connect(HttpRequestBase method) throws ParseException, ClientProtocolException, IOException {
CloseableHttpResponse response = null;
try {
response = closeableHttpClient.execute(method);
return new HttpResult(response.getStatusLine().getStatusCode(),
EntityUtils.toString(response.getEntity(), "UTF-8"));
} finally {
if (response != null) {
response.close();
}
}
}
@Override
public HttpResult doGet(String url) throws ParseException, ClientProtocolException, IOException {
HttpGet httpGet = new HttpGet(url);
HttpResult result = this.connect(httpGet);
return result;
}
@Override
public HttpResult doGet(String url, Map<String, String> params)
throws ParseException, ClientProtocolException, IOException, URISyntaxException {
HttpGet httpGet = new HttpGet(this.getUrl(url, params));
return this.connect(httpGet);
}
@Override
public HttpResult doGet(String url, Map<String, String> params, List<Header> headers)
throws ParseException, ClientProtocolException, IOException, URISyntaxException {
HttpGet httpGet = new HttpGet(this.getUrl(url, params));
if (headers != null) {
for (Header header : headers) {
httpGet.setHeader(header);
}
}
return this.connect(httpGet);
}
private String getUrl(String url, Map<String, String> params) throws URISyntaxException {
if (params != null) {
URIBuilder uriBuilder = new URIBuilder(url);
for (String key : params.keySet()) {
uriBuilder.addParameter(key, params.get(key));
}
return uriBuilder.build().toString();
}
return url;
}
@Override
public HttpResult doPost(String url, String json) throws ParseException, ClientProtocolException, IOException {
List<Header> headers = new ArrayList<Header>();
return this.doPost(url, json, headers);
}
@Override
public HttpResult doPost(String url, String json, List<Header> headers)
throws ParseException, ClientProtocolException, IOException {
if (url == null || json == null) {
return null;
}
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
if (headers != null) {
for (Header header : headers) {
httpPost.setHeader(header);
}
}
return this.connect(httpPost);
}
@Override
public HttpResult doPost(String url, String parameter, ContentType contentType)
throws ParseException, ClientProtocolException, IOException {
return this.doPost(url, parameter, null, contentType);
}
@Override
public HttpResult doPost(String url, String parameter, List<Header> headers, ContentType contentType)
throws ParseException, ClientProtocolException, IOException {
if (url == null || parameter == null) {
return null;
}
if (contentType == null) {
contentType = ContentType.APPLICATION_JSON;
}
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(parameter, contentType));
if (headers != null) {
for (Header header : headers) {
httpPost.setHeader(header);
}
}
return this.connect(httpPost);
}
@Override
public HttpResult doPost(String url, Map<String, String> params)
throws ParseException, ClientProtocolException, IOException {
return this.doPost(url, params, null);
}
@Override
public HttpResult doPost(String url, Map<String, String> params, List<Header> headers)
throws ParseException, ClientProtocolException, IOException {
return this.doPost(url, params, headers, null);
}
@Override
public HttpResult doPost(String url, Map<String, String> params, List<Header> headers, Charset charset)
throws ParseException, ClientProtocolException, IOException {
if (url == null || params == null) {
return null;
}
if (charset == null) {
charset = Consts.UTF_8;
}
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
for (String key : params.keySet()) {
parameters.add(new BasicNameValuePair(key, params.get(key)));
}
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters, charset.name());
httpPost.setEntity(formEntity);
if (headers != null) {
for (Header header : headers) {
httpPost.setHeader(header);
}
}
return this.connect(httpPost);
}
}
定义两个实现类,分别实现HTTP、HTTPS请求
HttpConnect和HttpsConnect继承AbstractHttpConnect抽象类,分别提供HTTP和HTTPS客户端的实例。HttpsConnect相对复杂一点,里边包含取消SSL检查的实例和检查证书的实例。
HttpConnect类
package com.light.httpclient.http.impl;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service("httpConnect")
public class HttpConnect extends AbstractHttpConnect {
@Override
@Autowired
public void setCloseableHttpClient(@Qualifier("httpclient")CloseableHttpClient closeableHttpClient) {
this.closeableHttpClient = closeableHttpClient;
}
}
HttpsConnect类
package com.light.httpclient.http.impl;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.net.ssl.SSLContext;
import org.apache.commons.lang.StringUtils;
import org.apache.http.config.Registry;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.IdleConnectionEvictor;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import com.light.httpclient.http.ssl.MySSLConnectionSocketFactory;
import com.light.httpclient.util.PropertiesUtil;
@Service("httpsConnect")
public class HttpsConnect extends AbstractHttpConnect {
private static final Logger logger = LoggerFactory.getLogger(HttpsConnect.class);
@Resource
private HttpClientBuilder httpClientBuilder;
/** 只在检查SSL时用到 */
private Integer maxTotal;
/** 只在检查SSL时用到 */
private Integer defaultMaxPerRoute;
private String keyStorePath;
private String keyStorepass;
@Override
@Autowired
public void setCloseableHttpClient(@Qualifier("httpsclient") CloseableHttpClient closeableHttpClient) {
this.closeableHttpClient = closeableHttpClient;
}
@PostConstruct
public void init() {
try {
String path = "/init.properties";
String maxTotals = PropertiesUtil.getValue(path, "httpclient.maxTotal");
if (!StringUtils.isBlank(maxTotals)) {
this.setMaxTotal(Integer.parseInt(maxTotals));
}
String defaultMaxPerRoutes = PropertiesUtil.getValue(path, "httpclient.maxTotal");
if (!StringUtils.isBlank(defaultMaxPerRoutes)) {
this.setDefaultMaxPerRoute(Integer.parseInt(defaultMaxPerRoutes));
}
} catch (Exception e) {
logger.error("初始化http配置信息异常:{}", e.getMessage());
}
}
/**
* <p>
* 注册带证书请求客户端
* </p>
*/
public void registry() {
Registry<ConnectionSocketFactory> socketFactoryRegistry = MySSLConnectionSocketFactory
.getSocketFactoryRegistry(custom(keyStorePath, keyStorepass));
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(
socketFactoryRegistry);
connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
connectionManager.setMaxTotal(maxTotal);
new IdleConnectionEvictor(connectionManager, 10000, TimeUnit.MILLISECONDS).start();
this.setCloseableHttpClient(httpClientBuilder.setConnectionManager(connectionManager).build());
}
public static SSLContext custom(String keyStorePath, String keyStorepass) {
SSLContext sc = null;
FileInputStream instream = null;
KeyStore trustStore = null;
try {
trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
instream = new FileInputStream(new File(keyStorePath));
trustStore.load(instream, keyStorepass.toCharArray());
// 相信自己的CA和所有自签名的证书
sc = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (instream != null) {
try {
instream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sc;
}
public Integer getDefaultMaxPerRoute() {
return defaultMaxPerRoute;
}
/**
* 仅在检查SSL的情况下起作用
*
* @param maxTotal
*/
public HttpsConnect setDefaultMaxPerRoute(Integer defaultMaxPerRoute) {
this.defaultMaxPerRoute = defaultMaxPerRoute;
return this;
}
public Integer getMaxTotal() {
return maxTotal;
}
/**
* 仅在检查SSL的情况下起作用
*
* @param maxTotal
*/
public HttpsConnect setMaxTotal(Integer maxTotal) {
this.maxTotal = maxTotal;
return this;
}
public String getKeyStorePath() {
return keyStorePath;
}
public HttpsConnect setKeyStorePath(String keyStorePath) {
this.keyStorePath = keyStorePath;
return this;
}
public String getKeyStorepass() {
return keyStorepass;
}
public HttpsConnect setKeyStorepass(String keyStorepass) {
this.keyStorepass = keyStorepass;
return this;
}
}
自定义连接池:MyPoolingHttpClientConnectionManager
目的是为了改变默认的注册信息,是否有安全问题还未验证。感觉应该没有。
package com.light.httpclient.http.ssl;
import org.apache.http.annotation.ThreadSafe;
import org.apache.http.config.Registry;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
@ThreadSafe
public class MyPoolingHttpClientConnectionManager extends PoolingHttpClientConnectionManager {
private static Registry<ConnectionSocketFactory> getDefaultRegistry() {
return MySSLConnectionSocketFactory.getSocketFactoryRegistry();
}
public MyPoolingHttpClientConnectionManager() {
super(getDefaultRegistry());
}
public MyPoolingHttpClientConnectionManager(final Registry<ConnectionSocketFactory> socketFactoryRegistry) {
super(socketFactoryRegistry, null, null);
}
}
MySSLConnectionSocketFactory类
取消SSL检查的相关代码
package com.light.httpclient.http.ssl;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.ssl.SSLContexts;
public class MySSLConnectionSocketFactory {
/** 取消检测SSL **/
private static TrustManager manager = new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
};
public static SSLConnectionSocketFactory getSocketFactory(SSLContext sslContext) {
return new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
}
public static SSLContext custom() {
SSLContext context = null;
try {
context = SSLContext.getInstance("SSL");
context.init(null, new TrustManager[] { manager }, null);
} catch (Exception e) {
e.printStackTrace();
}
return context;
}
public static SSLContext custom(String keyStorePath, String keyStorepass) {
SSLContext sc = null;
FileInputStream instream = null;
KeyStore trustStore = null;
try {
trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
instream = new FileInputStream(new File(keyStorePath));
trustStore.load(instream, keyStorepass.toCharArray());
// 相信自己的CA和所有自签名的证书
sc = SSLContexts.custom().loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()).build();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (instream != null) {
try {
instream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sc;
}
/**
* 取消SSL检测
* @return
*/
public static Registry<ConnectionSocketFactory> getSocketFactoryRegistry() {
// return RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE)
// .register("https", new SSLConnectionSocketFactory(custom())).build();
return RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", getSocketFactory(custom())).build();
}
/**
* 检测SSL
* @param keyStorePath 证书路径
* @param keyStorepass 证书秘钥
* @return
*/
public static Registry<ConnectionSocketFactory> getSocketFactoryRegistry(String keyStorePath, String keyStorepass) {
return RegistryBuilder.<ConnectionSocketFactory>create().register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", getSocketFactory(custom(keyStorePath, keyStorepass))).build();
}
}
HttpResult类
HTTP请求返回结果封装,可以在其中增加或删除属性,以满足不同需求。
package com.light.httpclient.http;
public class HttpResult {
/**状态码 */
private int status;
/**返回数据 */
private String data;
public HttpResult() {
}
public HttpResult(int status, String data) {
this.status = status;
this.data = data;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
@Override
public String toString() {
return String.format("HttpResult [status=%s, data=%s]", status, data);
}
}
spring.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<!-- 自动扫描两个包下的内容 ,将带有注解的类 纳入spring容器管理 -->
<context:component-scan base-package="com.light.httpclient"></context:component-scan>
<!-- 引入配置文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:init.properties</value>
</list>
</property>
</bean>
<!-- #=========================================Apache httpClient公共配置==========================================# -->
<!-- 定义连接管理器 -->
<bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig.Builder">
<!-- 创建连接的最长时间 -->
<property name="connectTimeout" value="${httpclient.connectTimeout}" />
<!-- 从连接池中获取到连接的最长时间 -->
<property name="connectionRequestTimeout" value="${httpclient.connectionRequestTimeout}" />
<!-- 数据传输的最长时间 -->
<property name="socketTimeout" value="${httpclient.socketTimeout}" />
<!-- 提交请求前测试连接是否可用 -->
<property name="staleConnectionCheckEnabled" value="${httpclient.staleConnectionCheckEnabled}" />
</bean>
<!-- 定义请求参数 -->
<bean id="requestConfig" class="org.apache.http.client.config.RequestConfig"
factory-bean="requestConfigBuilder" factory-method="build">
</bean>
<bean id="MILLISECONDS"
class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="staticField" value="java.util.concurrent.TimeUnit.MILLISECONDS" />
</bean>
<!-- #=========================================Apache httpClient通用配置==========================================# -->
<!-- 定义连接管理器 -->
<bean id="httpClientConnectionManager"
class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager"
destroy-method="close">
<!-- 最大连接数 -->
<property name="maxTotal" value="${httpclient.maxTotal}" />
<!-- 设置每个主机地址的并发数 -->
<property name="defaultMaxPerRoute" value="${httpclient.defaultMaxPerRoute}" />
</bean>
<!-- httpClient对象构建器 -->
<bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder">
<!-- 设置连接管理器 -->
<property name="connectionManager" ref="httpClientConnectionManager" />
<property name="defaultRequestConfig" ref="requestConfig" />
</bean>
<!-- 定义httpClient对象 -->
<bean id="httpclient" class="org.apache.http.impl.client.CloseableHttpClient"
factory-bean="httpClientBuilder" factory-method="build" scope="prototype">
</bean>
<!-- 定时清理无效连接 -->
<bean class="org.apache.http.impl.client.IdleConnectionEvictor"
init-method="start" destroy-method="shutdown">
<constructor-arg name="connectionManager" ref="httpClientConnectionManager" />
<constructor-arg name="sleepTime" value="5000" />
<constructor-arg name="sleepTimeUnit" ref="MILLISECONDS" />
<constructor-arg name="maxIdleTime" value="10000" />
<constructor-arg name="maxIdleTimeUnit" ref="MILLISECONDS" />
</bean>
<!-- #=========================================取消SSL认证配置==========================================# -->
<bean id="httpsClientConnectionManager"
class="com.light.httpclient.http.ssl.MyPoolingHttpClientConnectionManager"
destroy-method="close">
<!-- 最大连接数 -->
<property name="maxTotal" value="${httpclient.maxTotal}" />
<!-- 设置每个主机地址的并发数 -->
<property name="defaultMaxPerRoute" value="${httpclient.defaultMaxPerRoute}" />
</bean>
<bean id="httpsClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder">
<!-- 设置连接管理器 -->
<property name="connectionManager" ref="httpsClientConnectionManager" />
<property name="defaultRequestConfig" ref="requestConfig" />
</bean>
<bean id="httpsclient" class="org.apache.http.impl.client.CloseableHttpClient"
factory-bean="httpsClientBuilder" factory-method="build" scope="prototype">
</bean>
<!-- 清理无效连接 -->
<bean class="org.apache.http.impl.client.IdleConnectionEvictor"
init-method="start" destroy-method="shutdown">
<constructor-arg name="connectionManager" ref="httpsClientConnectionManager" />
<constructor-arg name="sleepTime" value="5000" />
<constructor-arg name="sleepTimeUnit" ref="MILLISECONDS" />
<constructor-arg name="maxIdleTime" value="10000" />
<constructor-arg name="maxIdleTimeUnit" ref="MILLISECONDS" />
</bean>
</beans>
init.properties文件
#Apache HttpClient配置
httpclient.maxTotal=1000
httpclient.defaultMaxPerRoute=300
httpclient.connectTimeout=5000
httpclient.connectionRequestTimeout=500
httpclient.socketTimeout=20000
httpclient.staleConnectionCheckEnabled=true