1. 程式人生 > 其它 >httpclient連線池及請求的簡單工具類

httpclient連線池及請求的簡單工具類

import com.alibaba.fastjson.JSON;
import org.apache.http.Header;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
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.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.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class HttpClientUtils {

    public static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);

    // 池化管理
    private static PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = null;

    private static CloseableHttpClient httpClient;// 它是執行緒安全的,所有的執行緒都可以使用它一起傳送http請求

    static {
        poolingHttpClientConnectionManager = initPool();
        getHttpClient();
    }


    public static PoolingHttpClientConnectionManager initPool(){

        SSLContextBuilder builder = new SSLContextBuilder();
        SSLConnectionSocketFactory sslsf = null;
        try {
            builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
            sslsf = new SSLConnectionSocketFactory(builder.build());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        // 配置同時支援 HTTP 和 HTPPS
        Registry<ConnectionSocketFactory> socketFactoryRegistry =
                RegistryBuilder.<ConnectionSocketFactory>create()
                        .register("http", PlainConnectionSocketFactory.getSocketFactory())
                        .register("https", sslsf)
                        .build();

        // 長連結保持時間長度60秒
        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
                new PoolingHttpClientConnectionManager(socketFactoryRegistry,null, null ,null,60,TimeUnit.SECONDS);

        // 設定最大連結數
        poolingHttpClientConnectionManager.setMaxTotal(200);
        // 單路由的併發數
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(50);
        return poolingHttpClientConnectionManager;
    }

    public static HttpClient getHttpClient(){
        if(null != httpClient){
            return httpClient;
        }
        synchronized (HttpClientUtils.class){
            if(null == httpClient){

                //設定請求相關的配置,例超時
                RequestConfig config = RequestConfig.custom().
                        setConnectTimeout(5000).
                        setConnectionRequestTimeout(5000).
                        setSocketTimeout(5000).
                        build();

                httpClient = HttpClients.custom()
                // 設定連線池
                .setConnectionManager(poolingHttpClientConnectionManager)
                //設定重試策略
                .setRetryHandler(new DefaultHttpRequestRetryHandler(3,true))
                // 設定請求相關的配置,例超時
                .setDefaultRequestConfig(config)
                // 構建客戶端
                .build();
                return httpClient;
            }
        }
        return httpClient;
    }

    public static String httpGet(String url, Map<String, Object> params , Header... heads) {

        if (params != null) {
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                sb.append("&").append(entry.getKey()).append("=").append(entry.getValue());
            }
            if (sb.length() > 0) {
                if (url.indexOf("?") > -1) {
                    url = url + sb.toString();
                } else {
                    sb.delete(0, 1);
                    url = url + "?" + sb.toString();
                }
            }
        }
        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = null;
        if (heads != null) {
            httpGet.setHeaders(heads);
        }
        try {
            response = httpClient.execute(httpGet);
            String result = EntityUtils.toString(response.getEntity());
            int code = response.getStatusLine().getStatusCode();
            if (code == HttpStatus.SC_OK) {
                return result;
            } else {
                logger.error("請求{}返回錯誤碼:{},{}", url, code,result);
                return null;
            }
        } catch (IOException e) {
            logger.error("http請求異常,{}",url,e);
        } finally {
            try {
                if (response != null)
                    response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    public static String httpPost(String uri, Object params, Header... heads) {
        HttpPost httpPost = new HttpPost(uri);
        CloseableHttpResponse response = null;
        try {
            if(params != null){
                StringEntity paramEntity = new StringEntity(JSON.toJSONString(params));
                paramEntity.setContentEncoding("UTF-8");
                paramEntity.setContentType("application/json");
                httpPost.setEntity(paramEntity);
            }
            if (heads != null) {
                httpPost.setHeaders(heads);
            }
            response = httpClient.execute(httpPost);
            int code = response.getStatusLine().getStatusCode();
            String result = EntityUtils.toString(response.getEntity());
            if (code == HttpStatus.SC_OK) {
                return result;
            } else {
                logger.error("請求{}返回錯誤碼:{},請求引數:{},{}", uri, code, params,result);
                return null;
            }
        } catch (IOException e) {
            logger.error("收集服務配置http請求異常", e);
        } finally {
            try {
                if(response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}