• Apache-Httpclient重试工具类封装


    • pom依赖
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpcore</artifactId>
        <version>4.4.4</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.7</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.76</version>
    </dependency>    
    • Http属性常量
    package com.coolw.codedemo.http;
    
    /**
     * @Description Http 属性请求常量
     * @Date 2021/5/11 11:46
     * @Author coolw
     */
    public interface HttpConstants {
    
        /**
         * 连接池最大连接数
         */
        int MAX_TOTAL_POOL = 256;
    
        /**
         * 每路连接最多连接数
         */
        int MAX_CONPERROUTE = 32;
    
        /**
         * socket超时时间
         */
        int SOCKET_TIMEOUT = 60 * 1000;
    
        /**
         * 连接请求超时时间
         */
        int CONNECTION_REQUEST_TIMEOUT = 5 * 1000;
    
        /**
         * 连接超时时间
         */
        int CONNECT_TIMEOUT = 5 * 1000;
    
        /**
         * http协议
         */
        String HTTP_PROTOCOL = "http";
    
        /**
         * https协议
         */
        String HTTPS_PROTOCOL = "https";
    
        /**
         * TLS
         */
        String SSL_CONTEXT = "TLS";
    
        /**
         * utf-8编码
         */
        String CHARSET_UTF_8 = "UTF-8";
    
        /**
         * application/json
         */
        String CONTENT_TYPE_JSON = "application/json";
    
        /**
         * content-type
         */
        String CONTENT_TYPE = "Content-Type";
    
    }
    • Http请求类型
    package com.coolw.codedemo.http;
    
    /**
     * @Description Http请求类型
     * @Date 2021/5/11 12:21
     * @Author coolw
     */
    public enum HttpMethod {
    
        GET, POST
    
    }
    • Http请求公共配置
    package com.coolw.codedemo.http;
    
    import org.apache.commons.lang3.StringUtils;
    import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
    import org.apache.http.client.methods.HttpRequestBase;
    import org.apache.http.entity.StringEntity;
    
    import java.util.Map;
    
    /**
     * @Description Http请求公共配置
     * @Date 2021/5/11 11:45
     * @Author coolw
     */
    public class HttpRequestConfig {
    
        /**
         * 返回默认的content-type: application/json
         */
        protected static String getDefaultContentType() {
            return HttpConstants.CONTENT_TYPE_JSON;
        }
    
        /**
         * 设置默认的content-Type:application/json
         */
        protected static void setContentTypeApplicationJson(HttpRequestBase requestBase) {
            requestBase.setHeader(HttpConstants.CONTENT_TYPE, HttpConstants.CONTENT_TYPE_JSON);
        }
    
        /**
         * 设置content-Type
         */
        protected static void setContentType(HttpRequestBase httpBase, String contentType) {
            if (StringUtils.isNotBlank(contentType)) {
                contentType = getDefaultContentType();
            }
            httpBase.setHeader(HttpConstants.CONTENT_TYPE, contentType);
        }
    
        /**
         * 设置请求体
         */
        protected static void setHttpBody(HttpEntityEnclosingRequestBase httpRequest, String body) {
            if (StringUtils.isBlank(body)) {
                return;
            }
            StringEntity entity = new StringEntity(body, HttpConstants.CHARSET_UTF_8);
            entity.setContentEncoding(HttpConstants.CHARSET_UTF_8);
            entity.setContentType(HttpConstants.CHARSET_UTF_8);
            httpRequest.setEntity(entity);
        }
    
        /**
         * 设置头部参数
         */
        protected static void setHeader(HttpRequestBase httpBase, Map<String, String> headerMap) {
            if (headerMap == null || headerMap.size() == 0) {
                return;
            }
            for (Map.Entry<String, String> entry : headerMap.entrySet()) {
                httpBase.addHeader(entry.getKey(), entry.getValue());
            }
        }
    
    }
    • Http连接工厂
    package com.coolw.codedemo.http;
    
    import org.apache.http.client.config.RequestConfig;
    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.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    /**
     * @Description HttpClient 连接工厂
     * @Date 2021/5/11 12:26
     * @Author coolw
     */
    public class HttpClientConnectFactory {
    
        private static PoolingHttpClientConnectionManager cm = null;
    
        /**
         * 初始化连接池
         */
        static {
            SSLContext sslcontext;
            try {
                sslcontext = createIgnoreVerifySSL();
                ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
                Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                        .register(HttpConstants.HTTP_PROTOCOL, plainsf)
                        .register(HttpConstants.HTTPS_PROTOCOL, getSSLConnectionSocketFactory(sslcontext))
                        .build();
                cm = new PoolingHttpClientConnectionManager(registry);
                cm.setMaxTotal(HttpConstants.MAX_TOTAL_POOL);
                cm.setDefaultMaxPerRoute(HttpConstants.MAX_CONPERROUTE);
            } catch (Exception e) {
                e.getStackTrace();
            }
        }
    
        /**
         * 获取 HttpClient 连接
         */
        public static CloseableHttpClient getHttpClient() {
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectionRequestTimeout(HttpConstants.CONNECTION_REQUEST_TIMEOUT)
                    .setConnectTimeout(HttpConstants.CONNECT_TIMEOUT)
                    .setSocketTimeout(HttpConstants.SOCKET_TIMEOUT)
                    .build();
            CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
                    .setDefaultRequestConfig(requestConfig)
                    .setRetryHandler(new HttpRequestRetryHandler())
                    .setConnectionManagerShared(true)
                    .build();
            return httpClient;
        }
    
        /**
         * 创建 SSLContext
         */
        private static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
            SSLContext sc = SSLContext.getInstance(HttpConstants.SSL_CONTEXT);
            X509TrustManager trustManager = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
    
                }
    
                @Override
                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
    
                }
    
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            sc.init(null, new TrustManager[]{trustManager}, null);
            return sc;
        }
    
        /**
         * 获取 SSLConnectionSocketFactory
         */
        private static ConnectionSocketFactory getSSLConnectionSocketFactory(SSLContext sslcontext) {
            return new SSLConnectionSocketFactory(sslcontext, NoopHostnameVerifier.INSTANCE);
        }
    
    }
    • Http重试处理
    package com.coolw.codedemo.http;
    
    import org.apache.http.HttpEntityEnclosingRequest;
    import org.apache.http.HttpRequest;
    import org.apache.http.NoHttpResponseException;
    import org.apache.http.client.protocol.HttpClientContext;
    import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
    import org.apache.http.protocol.HttpContext;
    
    import javax.net.ssl.SSLException;
    import javax.net.ssl.SSLHandshakeException;
    import java.io.IOException;
    import java.io.InterruptedIOException;
    import java.net.UnknownHostException;
    
    /**
     * @Description Http重试处理机制
     * @Date 2021/5/11 10:20
     * @Author coolw
     */
    public class HttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {
    
        /**
         * 重试次数,默认3次
         */
        private int retryCount = 3;
    
        public HttpRequestRetryHandler() {
            super();
        }
    
        public HttpRequestRetryHandler(int retryCount) {
            super();
            this.retryCount = retryCount;
        }
    
        @Override
        public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
            // 重试次数已上限,不重试
            if (executionCount >= retryCount) {
                return false;
            }
            if (exception instanceof SSLHandshakeException) {
                return false;
            }
            if (exception instanceof UnknownHostException) {
                return false;
            }
            if (exception instanceof SSLException) {
                return false;
            }
    
            // 重试
            if (exception instanceof NoHttpResponseException) {
                return true;
            }
            if (exception instanceof InterruptedIOException) {
                return true;
            }
    
            HttpClientContext clientContext = HttpClientContext.adapt(context);
            HttpRequest request = clientContext.getRequest();
            // 如果请求是幂等的,重试
            if (!(request instanceof HttpEntityEnclosingRequest)) {
                return true;
            }
            return false;
        }
    
    }
    • Http工具类
    package com.coolw.codedemo.http;
    
    import com.alibaba.fastjson.JSON;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.http.HttpStatus;
    import org.apache.http.client.methods.*;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.util.EntityUtils;
    
    import java.io.IOException;
    import java.lang.reflect.Type;
    import java.util.Map;
    
    /**
     * @Description Http工具类
     * @Date 2021/5/11 12:17
     * @Author coolw
     */
    @Slf4j
    public class BaseHttpUtils extends HttpRequestConfig {
    
        /**
         * 创建Http请求对象
         */
        protected static HttpRequestBase createHttpRequestBase(HttpMethod method, String url) {
            switch (method) {
                case GET:
                    return new HttpGet(url);
                case POST:
                    return new HttpPost(url);
                default:
                    return new HttpGet(url);
            }
        }
    
        protected static String exec(String url, HttpMethod method, Map<String, String> headerMap, String contentType, String body) {
            HttpRequestBase httpRequest = createHttpRequestBase(method, url);
            setHeader(httpRequest, headerMap);
            setContentType(httpRequest, contentType);
            if (httpRequest instanceof HttpEntityEnclosingRequestBase) {
                setHttpBody((HttpEntityEnclosingRequestBase) httpRequest, body);
            }
            CloseableHttpResponse response = null;
            try (CloseableHttpClient httpClient = HttpClientConnectFactory.getHttpClient()) {
                response = httpClient.execute(httpRequest);
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode == HttpStatus.SC_OK) {
                    return EntityUtils.toString(response.getEntity(), "utf-8");
                }
                log.warn("http exec status fail. url={},statusCode={}", url, statusCode);
            } catch (IOException e) {
                log.error("http exec error. url:{},body={}", url, body, e);
            }
            return JSON.toJSONString(response);
        }
    
        @SuppressWarnings("unchecked")
        public static <T> T responseHandle(String apiResult, T defaultResult, Type type) {
            if (StringUtils.isBlank(apiResult)) {
                return defaultResult;
            }
            try {
                return (T) JSON.parseObject(apiResult, type);
            } catch (Exception e) {
                return defaultResult;
            }
        }
    
    }
    • Http多参工具类
    package com.coolw.codedemo.http;
    
    import java.util.Map;
    
    /**
     * @Description 多参Http工具类
     * @Date 2021/5/11 13:54
     * @Author coolw
     */
    public class MultiHttpUtils extends BaseHttpUtils {
    
        /**
         * exec请求。content-Type 默认 application/json
         *
         * @param method 请求类型
         * @param url    请求地址
         * @return String
         */
        public static String exec(HttpMethod method, String url) {
            return exec(method, url, null, getDefaultContentType(), null);
        }
    
        /**
         * exec请求,通过以下参数获取数据
         *
         * @param method    请求类型
         * @param url       请求地址
         * @param headerMap 请求头部参数
         * @return String
         */
        public static String exec(HttpMethod method, String url, Map<String, String> headerMap) {
            return exec(method, url, headerMap, getDefaultContentType(), null);
        }
    
        /**
         * exec请求。content-Type 默认 application/json
         *
         * @param method 请求类型
         * @param url    请求地址
         * @param body   请求内容
         * @return String
         */
        public static String exec(HttpMethod method, String url, String body) {
            return exec(method, url, null, getDefaultContentType(), body);
        }
    
        /**
         * exec请求
         *
         * @param method      请求类型
         * @param url         请求地址
         * @param contentType 请求内容体类型
         * @param body        请求内容
         * @return String
         */
        public static String exec(HttpMethod method, String url, String contentType, String body) {
            return exec(method, url, null, contentType, body);
        }
    
        /**
         * exec请求。content-Type 默认 application/json
         *
         * @param method    请求类型
         * @param url       请求地址
         * @param headerMap 请求头部参数
         * @param body      请求内容
         * @return String
         */
        public static String exec(HttpMethod method, String url, Map<String, String> headerMap, String body) {
            return exec(method, url, headerMap, getDefaultContentType(), body);
        }
    
        /**
         * exec请求
         *
         * @param method      请求类型
         * @param url         请求地址
         * @param headerMap   请求头部参数
         * @param contentType 请求内容体类型
         * @param body        请求内容
         * @return String
         */
        public static String exec(HttpMethod method, String url, Map<String, String> headerMap, String contentType, String body) {
            return exec(url, method, headerMap, contentType, body);
        }
    
    }
  • 相关阅读:
    Centos8 安装mongodb
    java 时间处理
    从技术走向管理李元芳履职记 读书记录
    debian基本操作
    centos8 安装kudu
    k8s api调用示例
    idea other settings
    C# Random生成相同随机数的解决方案
    DropDownList绑定选择数据报错问题
    离谱
  • 原文地址:https://www.cnblogs.com/lwcode6/p/14789327.html
Copyright © 2020-2023  润新知