zoukankan      html  css  js  c++  java
  • 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);
        }
    
    }
  • 相关阅读:
    CodeForces 7B
    CodeForces 4D
    离散化
    线段树入门
    洛谷 P3951 小凯的疑惑(赛瓦维斯特定理)
    Codeforces 1295D Same GCDs (欧拉函数)
    Codeforces 1295C Obtain The String (二分)
    Codeforces 1295B Infinite Prefixes
    Codeforces 1295A Display The Number(思维)
    Codeforces 1294F Three Paths on a Tree(树的直径,思维)
  • 原文地址:https://www.cnblogs.com/lwcode6/p/14789327.html
Copyright © 2011-2022 走看看