All Downloads are FREE. Search and download functionalities are using the official Maven repository.

top.wboost.common.util.HttpClientUtil Maven / Gradle / Ivy

There is a newer version: 4.0.1
Show newest version
package top.wboost.common.util;

import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
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.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import top.wboost.common.base.entity.HttpRequestBuilder;
import top.wboost.common.base.entity.RequestEntity;
import top.wboost.common.base.enums.CharsetEnum;
import top.wboost.common.log.util.LoggerUtil;
import top.wboost.common.system.exception.ConnectionException;
import top.wboost.common.utils.web.utils.FileUtil;
import top.wboost.common.utils.web.utils.PropertiesUtil;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;

/**
 * HttpClient工具类
 * @author jwSun
 * @date 2017年6月14日 上午11:00:34
 */
public class HttpClientUtil {

    // 最大连接数
    public final static int MAX_TOTAL_CONNECTIONS = Integer
            .parseInt(PropertiesUtil.getPropertyOrDefault("common.util.httpClientUtil.MAX_TOTAL_CONNECTIONS", "100"));
    // 获取连接的最大等待时间
    public final static int WAIT_TIMEOUT = Integer
            .parseInt(PropertiesUtil.getPropertyOrDefault("common.util.httpClientUtil.WAIT_TIMEOUT", "30000"));// 30s
    // 每个路由最大连接数
    public final static int MAX_ROUTE_CONNECTIONS = Integer
            .parseInt(PropertiesUtil.getPropertyOrDefault("common.util.httpClientUtil.MAX_ROUTE_CONNECTIONS", "50"));
    // 连接超时时间
    public final static int CONNECT_TIMEOUT = Integer
            .parseInt(PropertiesUtil.getPropertyOrDefault("common.util.httpClientUtil.CONNECT_TIMEOUT", "10000"));// 10s
    // 读取超时时间
    public final static int READ_TIMEOUT = Integer
            .parseInt(PropertiesUtil.getPropertyOrDefault("common.util.httpClientUtil.READ_TIMEOUT", "10000"));// 10s
    //允许跳转
    public final static boolean REDIRECTS_ENABLED = true;
    //连接池
    private static final PoolingHttpClientConnectionManager poolManager;
    //请求重试处理
    private static final HttpRequestRetryHandler httpRequestRetryHandler;
    //请求配置
    private static final RequestConfig requestConfig;
    private static Logger log = LoggerUtil.getLogger(HttpClientUtil.class);
    private static CloseableHttpClient httpClient = getNewHttpClient();

    static {
        poolManager = getConnectionManager();
        httpRequestRetryHandler = getHttpRequestRetryHandler();
        requestConfig = getRequestConfig();
    }

    public static PoolingHttpClientConnectionManager getConnectionManager() {
        ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
        LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
        Registry registry = RegistryBuilder. create()
                .register("http", plainsf).register("https", sslsf).build();
        PoolingHttpClientConnectionManager poolManager = new PoolingHttpClientConnectionManager(registry);

        // 设置最大连接数
        poolManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
        // 设置获取连接的最大等待时间
        poolManager.setDefaultMaxPerRoute(MAX_ROUTE_CONNECTIONS);
        return poolManager;
    }

    public static HttpRequestRetryHandler getHttpRequestRetryHandler() {
        return new HttpRequestRetryHandler() {
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                if (executionCount >= 5) {// 如果已经重试了5次,就放弃
                    return false;
                }
                if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
                    return true;
                }
                if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
                    return false;
                }
                if (exception instanceof InterruptedIOException) {// 超时
                    return false;
                }
                if (exception instanceof UnknownHostException) {// 目标服务器不可达
                    return false;
                }
                if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
                    return false;
                }
                if (exception instanceof SSLException) {// ssl握手异常
                    return false;
                }
                HttpClientContext clientContext = HttpClientContext.adapt(context);
                HttpRequest request = clientContext.getRequest();
                // 如果请求是幂等的,就再次尝试
                if (!(request instanceof HttpEntityEnclosingRequest)) {
                    return true;
                }
                return false;
            }
        };
    }

    public static RequestConfig getRequestConfig() {
        return RequestConfig.custom().setConnectTimeout(CONNECT_TIMEOUT).setRedirectsEnabled(REDIRECTS_ENABLED).build();
    }

    public static CloseableHttpClient getNewHttpClient() {
        CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(poolManager)
                .setRetryHandler(httpRequestRetryHandler).setDefaultRequestConfig(requestConfig).build();
        return httpClient;
    }

    public static CloseableHttpClient getHttpClient() {
        return httpClient;
    }

    /**
     * WebUtil快速转HttpclientUtil
     * @author jwSun
     * @date 2017年6月14日 下午4:18:17
     * @param requestEntity
     * @return
     */
    public static ResponseEntity execute(RequestEntity requestEntity) {
        CloseableHttpClient httpClient = getHttpClient();
        ResponseEntity responseEntity = execute(requestEntity, httpClient);
        return responseEntity;
    }

    /**
     * 原生HttpClient使用方法
     * @author jwSun
     * @date 2017年6月14日 下午4:21:29
     * @param request
     * @return
     */
    public static ResponseEntity execute(HttpRequestBase request) {
        CloseableHttpClient httpClient = getHttpClient();
        ResponseEntity responseEntity = execute(request, httpClient);
        return responseEntity;
    }

    /**
     * 推荐使用
     * ResponseEntity get = HttpClientUtil.execute(HttpRequestBuilder.get("url").addParameter("key", "value"));
     * ResponseEntity post = HttpClientUtil.execute(HttpRequestBuilder.post("url").addParameter("key", "value"))
     * @author jwSun
     * @date 2017年6月15日 上午10:41:05
     * @param httpRequestBuilder
     * @return
     */
    public static ResponseEntity execute(HttpRequestBuilder httpRequestBuilder) {
        return execute(httpRequestBuilder.build());
    }

    /**
     * WebUtil快速转HttpclientUtil
     * @author jwSun
     * @date 2017年6月14日 下午4:18:17
     * @param requestEntity
     * @return
     */
    public static ResponseEntity execute(RequestEntity requestEntity, HttpClient httpClient) {
        HttpRequestBase request;
        HttpMethod method = requestEntity.getMethod();
        if (method == HttpMethod.GET) {
            request = new HttpGet(requestEntity.getUrl());
        } else if (method == HttpMethod.POST) {
            HttpPost httpPost = new HttpPost(requestEntity.getUrl());
            StringEntity stringEntity = new StringEntity(requestEntity.getBody(), requestEntity.getCharset());
            stringEntity.setContentType(requestEntity.getHeaders().getContentType().toString());
            httpPost.setEntity(stringEntity);
            request = httpPost;
        } else {
            throw new RuntimeException("暂时只支持 get 与 post");
        }
        return execute(request, httpClient);
    }

    /**
     * 原生HttpClient使用方法
     * @author jwSun
     * @date 2017年6月14日 下午4:21:29
     * @param request
     * @return
     */
    public static ResponseEntity execute(HttpRequestBase request, HttpClient httpClient) {
        try {
            HttpResponse response = httpClient.execute(request);
            HttpEntity responseEntity = response.getEntity();
            String body = EntityUtils.toString(responseEntity, CharsetEnum.UTF_8.getCharset());
            EntityUtils.consume(response.getEntity());
            return ResponseEntity.status(response.getStatusLine().getStatusCode()).body(body);
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new ConnectionException(request.toString(), e);
        } finally {
            request.releaseConnection();
        }
    }

    public static byte[] executeDownload(HttpRequestBase request, HttpClient httpClient) {
        try {
            HttpResponse response = httpClient.execute(request);
            HttpEntity responseEntity = response.getEntity();
            return FileUtil.importFileBytes(responseEntity.getContent());
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new ConnectionException(request.toString(), e);
        } finally {
            request.releaseConnection();
        }
    }

    /**
     * 推荐使用
     * ResponseEntity get = HttpClientUtil.execute(HttpRequestBuilder.get("url").addParameter("key", "value"));
     * ResponseEntity post = HttpClientUtil.execute(HttpRequestBuilder.post("url").addParameter("key", "value"))
     * @author jwSun
     * @date 2017年6月15日 上午10:41:05
     * @param httpRequestBuilder
     * @return
     */
    public static ResponseEntity execute(HttpRequestBuilder httpRequestBuilder, HttpClient httpClient) {
        return execute(httpRequestBuilder.build(), httpClient);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy