工具类之HttpClient各种请求封装

一、引入maven依赖

        
        
            org.apache.httpcomponents
            httpasyncclient
            4.1
        

 二、配置HttpClient服务信息

# http配置服务
http:
  # 最大连接数
  maxTotal: 100
  # 并发数
  defaultMaxPerRoute : 20
  # 创建连接的最长时间
  connectTimeout: 1000
  # 从连接池中获取到连接的最长时间
  connectionRequestTimeout: 500
  # 数据传输的最长时间
  socketTimeout: 10000
  # 提交请求前测试连接是否可用
  staleConnectionCheckEnabled: true

三、加载配置信息

/**
 * @program: springboot-mybatis-swagger
 * @description: http请求
 * @author: Mario
 * @create: 2019-07-15 09:06
 **/
@Configuration
public class HttpClientConfig {
    @Value("${http.maxTotal}")
    private Integer maxTotal;

    @Value("${http.defaultMaxPerRoute}")
    private Integer defaultMaxPerRoute;

    @Value("${http.connectTimeout}")
    private Integer connectTimeout;

    @Value("${http.connectionRequestTimeout}")
    private Integer connectionRequestTimeout;

    @Value("${http.socketTimeout}")
    private Integer socketTimeout;

    @Value("${http.staleConnectionCheckEnabled}")
    private boolean staleConnectionCheckEnabled;

    /**
     * 首先实例化一个连接池管理器,设置最大连接数、并发连接数
     * @return
     */
    @Bean(name = "httpClientConnectionManager")
    public PoolingHttpClientConnectionManager getHttpClientConnectionManager(){
        PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
        //最大连接数
        httpClientConnectionManager.setMaxTotal(maxTotal);
        //并发数
        httpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
        return httpClientConnectionManager;
    }

    /**
     * 实例化连接池,设置连接池管理器。
     * 这里需要以参数形式注入上面实例化的连接池管理器
     * @param httpClientConnectionManager
     * @return
     */
    @Bean(name = "httpClientBuilder")
    public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager")PoolingHttpClientConnectionManager httpClientConnectionManager){

        //HttpClientBuilder中的构造方法被protected修饰,所以这里不能直接使用new来实例化一个HttpClientBuilder,可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();

        httpClientBuilder.setConnectionManager(httpClientConnectionManager);

        return httpClientBuilder;
    }

    /**
     * 注入连接池,用于获取httpClient
     * @param httpClientBuilder
     * @return
     */
    @Bean
    public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder){
        return httpClientBuilder.build();
    }

    /**
     * Builder是RequestConfig的一个内部类
     * 通过RequestConfig的custom方法来获取到一个Builder对象
     * 设置builder的连接信息
     * 这里还可以设置proxy,cookieSpec等属性。有需要的话可以在此设置
     * @return
     */
    @Bean(name = "builder")
    public RequestConfig.Builder getBuilder(){
        RequestConfig.Builder builder = RequestConfig.custom();
        return builder.setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(connectionRequestTimeout)
                .setSocketTimeout(socketTimeout)
                .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled);
    }

    /**
     * 使用builder构建一个RequestConfig对象
     * @param builder
     * @return
     */
    @Bean
    public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder){
        return builder.build();
    }
}

四、线程开启与关闭 

/**
 * @program: springboot-mybatis-swagger
 * @description: http启动与关闭
 * @author: Mario
 * @create: 2019-07-15 09:09
 **/
@Component
public class IdleConnectionEvictor extends Thread {
    @Autowired
    private HttpClientConnectionManager connMgr;

    private volatile boolean shutdown;

    public IdleConnectionEvictor() {
        super();
        super.start();
    }

    @Override
    public void run() {
        try {
            while (!shutdown) {
                synchronized (this) {
                    wait(5000);
                    // 关闭失效的连接
                    connMgr.closeExpiredConnections();
                }
            }
        } catch (InterruptedException ex) {
            // 结束
        }
    }

    //关闭清理无效连接的线程
    public void shutdown() {
        shutdown = true;
        synchronized (this) {
            notifyAll();
        }
    }
}

五、请求结果封装

/**
 * @program: springboot-mybatis-swagger
 * @description: HTTP请求结果
 * @author: Mario
 * @create: 2019-07-15 09:10
 **/
@Data
public class HttpResultDTO {
    // 响应码
    @NonNull
    private Integer code;

    // 响应体
    @NonNull
    private String body;
}

六、各种请求封装 

Get/Post等请求可能封装了多余参数,后续可以自行拆解

@Component
public class HttpAPIController {

    private static CloseableHttpClient httpClient;

    /**
     * 信任SSL证书
     */
    static {
        try {
            SSLContext sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL)
                    .loadTrustMaterial((x, y) -> true).build();
            /**
             * 一、连接超时:connectionTimeout-->指的是连接一个url的连接等待时间
             * 二、读取数据超时:SocketTimeout-->指的是连接上一个url,获取response的返回等待时间
             */
            RequestConfig config = RequestConfig.custom().setConnectTimeout(500000).setSocketTimeout(500000).build();
            httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).setSSLContext(sslContext)
                    .setSSLHostnameVerifier((x, y) -> true).build();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Autowired
    private RequestConfig config;

    /**
     * @description GET---不含参
     * @param url
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:02
     */
    /*public HttpResultDTO doGet(String url) throws Exception {
        // 声明 http get 请求
        HttpGet httpGet = new HttpGet(url);

        // 装载配置信息
        httpGet.setConfig(config);

        // 允许重定向
        httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);

        // 发起请求
        CloseableHttpResponse response = this.httpClient.execute(httpGet);

        // 返回响应代码与内容
        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));
    }*/

    /**
     * @description GET---含请求头
     * @param url
	 * @param headers
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:04
     */
   /* public HttpResultDTO doGetWithHeaders(String url, Map headers) throws Exception {
        // 声明 http get 请求
        HttpGet httpGet = new HttpGet(url);

        // 装载配置信息
        httpGet.setConfig(config);

        // 设置请求头
        if (headers != null) {
            for (String key : headers.keySet()) {
                String value = headers.get(key).toString();
                httpGet.addHeader(key,value);
            }
        }

        // 允许重定向
        httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);

        // 发起请求
        CloseableHttpResponse response = this.httpClient.execute(httpGet);

        // 返回响应代码与内容
        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));
    }*/

    /**
     * @description GET---含Map请求参数
     * @param url
	 * @param mapParams
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:06
     */
    /*public HttpResultDTO doGetWithParams(String url, Map mapParams) throws Exception {
        // 包装URL
        URIBuilder uriBuilder = new URIBuilder(url);

        if (mapParams != null) {
            // 遍历map,拼接请求参数
            for (Map.Entry entry : mapParams.entrySet()) {
                uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());
            }
        }

        // 调用不带参数的get请求
        return this.doGet(uriBuilder.build().toString());

    }*/
    
    /**
     * @description GET---含Map请求参数且含请求头
     * @param url
	 * @param mapParams
	 * @param headers
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:08
     */
    public HttpResultDTO doGetWithParamsAndHeaders(String url, Map mapParams , Map headers) throws Exception {
        // 声明 http get 请求
        HttpGet httpGet = new HttpGet(url);

        // 装载配置信息
        httpGet.setConfig(config);

        // 允许重定向
        httpGet.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS,true);
        
        // 包装请求行
        if (mapParams != null) {
            // 包装URL
            URIBuilder uriBuilder = new URIBuilder(url);
            // 遍历map,拼接请求参数
            for (Map.Entry entry : mapParams.entrySet()) {
                uriBuilder.setParameter(entry.getKey(), entry.getValue().toString());
            }
            // 新的请求行
            url = uriBuilder.build().toString();
        }
        
        // 设置请求头
        if (headers != null) {
            for (String key : headers.keySet()) {
                String value = headers.get(key).toString();
                httpGet.addHeader(key,value);
            }
        }

        // 发起请求
        CloseableHttpResponse response = this.httpClient.execute(httpGet);

        // 返回响应代码与内容
        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));
    }



    /**
     * @description POST--不含参
     * @param url
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:14
     */
    /*public HttpResultDTO doPost(String url) throws Exception {
        // 声明httpPost请求
        HttpPost httpPost = new HttpPost(url);
        
        // 加入配置信息
        httpPost.setConfig(config);
        
        // 发起请求
        CloseableHttpResponse response = this.httpClient.execute(httpPost);

        // 返回响应代码与内容
        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));
    }*/

    /**
     * @description POST---含参
     * @param url
	 * @param params
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:16
     */
    /*public HttpResultDTO doPostWithParams(String url, Map params) throws Exception {
        // 声明httpPost请求
        HttpPost httpPost = new HttpPost(url);

        // 加入配置信息
        httpPost.setConfig(config);

        // 判断map是否为空,不为空则进行遍历,封装from表单对象
        if (params != null) {
            List list = new ArrayList();
            for (Map.Entry entry : params.entrySet()) {
                list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
            }
            // 构造from表单对象
            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8");

            // 把表单放到post里
            httpPost.setEntity(urlEncodedFormEntity);
        }

        // 发起请求
        CloseableHttpResponse response = this.httpClient.execute(httpPost);

        // 返回响应代码与内容
        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));
    }*/

    /**
     * @description POST---含请求头
     * @param url
	 * @param headers
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:17
     */
    /*public HttpResultDTO doPostWithHeaders(String url, Map headers) throws Exception {
        // 声明httpPost请求
        HttpPost httpPost = new HttpPost(url);

        // 加入配置信息
        httpPost.setConfig(config);

        // 设置请求头
        if (headers != null) {
            for (String key : headers.keySet()) {
                String value = headers.get(key).toString();
                httpPost.addHeader(key,value);
            }
        }

        // 发起请求
        CloseableHttpResponse response = this.httpClient.execute(httpPost);

        // 返回响应代码与内容
        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));
    }*/


    /**
     * @description POST---含参(请求路径、Map参数、请求头)
     * @param url
	 * @param mapParams
	 * @param headers
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:22
     */
    public HttpResultDTO doPostWithParamsAndHeaders(String url, Map mapParams , Map headers) throws Exception {
        // 声明httpPost请求
        HttpPost httpPost = new HttpPost(url);
        // 加入配置信息
        httpPost.setConfig(config);

        // 判断map是否为空,不为空则进行遍历,封装from表单对象
        if (mapParams != null) {
            List list = new ArrayList();
            for (Map.Entry entry : mapParams.entrySet()) {
                list.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
            }
            // 构造from表单对象
            UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(list, "UTF-8");

            // 把表单放到post里
            httpPost.setEntity(urlEncodedFormEntity);
        }

        // 设置请求头
        if (headers != null) {
            for (String key : headers.keySet()) {
                String value = headers.get(key).toString();
                httpPost.addHeader(key,value);
            }
        }

        // 发起请求
        CloseableHttpResponse response = this.httpClient.execute(httpPost);
        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));
    }



    /**
     * @description POST---含参(请求路径、JSON参数串、请求头)
     * @param url
	 * @param jsonParam
	 * @param headers
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:20
     */
    public static HttpResultDTO doPostWithJsonParamAndHeaders(String url, String jsonParam, Map headers) throws Exception {
        // 声明httpPost请求
        HttpPost httpPost = new HttpPost(url);

        // 设置请求头
        if (headers != null) {
            for (String key : headers.keySet()) {
                String value = headers.get(key).toString();
                httpPost.addHeader(key, value);
            }
        }

        // 设置以Json数据方式发送
        StringEntity stringEntity = new StringEntity(jsonParam, "utf-8");
        stringEntity.setContentType("application/json");
        httpPost.setEntity(stringEntity);

        // 发起请求
        CloseableHttpResponse response = httpClient.execute(httpPost);

        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));
    }

    /**
     * @description PUT---含参(请求路径、JSON参数串、请求头)
     * @param url
	 * @param jsonParam
	 * @param headers
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:32
     */
    public static HttpResultDTO doPutWithJsonAndHeaders(String url,String jsonParam,Map headers) throws Exception{
        // 声明httpPut请求
        HttpPut httpPut = new HttpPut(url);

        //设置header
        httpPut.setHeader("Content-type", "application/json");
        if (headers != null && headers.size() > 0) {
            for (Map.Entry entry : headers.entrySet()) {
                httpPut.setHeader(entry.getKey(),entry.getValue());
            }
        }

        //组织请求参数
        if (StringUtils.isNotEmpty(jsonParam)) {
            StringEntity stringEntity = new StringEntity(jsonParam, "utf-8");
            httpPut.setEntity(stringEntity);
        }
        
        // 发起请求
        CloseableHttpResponse response = httpClient.execute(httpPut);

        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));
    }

    /**
     * @description DELETE---含参(请求路径、请求头)
     * @param url
	 * @param headers
     * @return com.mark.dc2.DTO.HttpResultDTO
     * @author Mario
     * @date 2019/7/23 9:37
     */
    public static HttpResultDTO doDeleteWithHeaders(String url,Map headers) throws Exception{
        // 声明httpDelete请求
        HttpDelete httpDelete = new HttpDelete(url);

        //设置header
        if (headers != null && headers.size() > 0) {
            for (Map.Entry entry : headers.entrySet()) {
                httpDelete.setHeader(entry.getKey(),entry.getValue());
            }
        }
        // 发起请求
        CloseableHttpResponse response = httpClient.execute(httpDelete);

        return new HttpResultDTO(response.getStatusLine().getStatusCode(), EntityUtils.toString(
                response.getEntity(), "UTF-8"));

    }
}

 

你可能感兴趣的:(工具类)