简单易用的httpclient封装

简单易用的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

GitHub地址:https://github.com/gaoyaguang/httpclient-test

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值