接続プールHttpClientUtilとHTTPクライアントツール

一、背景

事業開発は、多くの場合、HTTP / HTTPSに要求を送信することにより、下流のサービスに遭遇します。繰り返し作成し、車輪に論理的な書き込みのHttpClient、および性能、機能ムラたびに。ここでは、高性能、汎用ツールベルトのHttpクライアントの接続プールを共有します。

:再現し、労働の作者の成果を尊重してください、元のリンク明記してくださいhttps://www.cnblogs.com/waterystone/p/11551280.htmlを

第二に、特性

  • ApacheのパフォーマンスベースのHTTPクライアントorg.apache.http.client.HttpClient。
  • デフォルトの接続プール20、200の最大数は、システム変数= -Dadu.common.http.max.totalで指定することができます。
  • 接続プールのデフォルトルーティングごとの接続の最大数は2であり、-Dadu.common.http.max.per.route = 10システム変数で指定することができます。
  • タイムアウトはhttpOptionsセットにより、設定することができます。
  • HttpOptionsによって設定され、再試行してください。

第三に、ソース

参考:https://github.com/waterystone/adu-test/blob/master/src/main/java/com/adu/utils/HttpClientUtil.java

 

パッケージcom.adu.utils。

輸入com.adu.Constants。
輸入com.adu.handler.HttpRequestRetryHandler。
輸入com.adu.model.HttpOptions。
輸入org.apache.http.HttpEntity。
輸入org.apache.http.NameValuePair; 
輸入org.apache.http.client.config.RequestConfig; 
輸入org.apache.http.client.entity.UrlEncodedFormEntity。
輸入org.apache.http.client.methods.CloseableHttpResponse。
輸入org.apache.http.client.methods.HttpGet; 
輸入org.apache.http.client.methods.HttpPost; 
輸入org.apache.http.client.methods.HttpRequestBase; 
輸入org.apache.http.client.utils.URIBuilder。
輸入org.apache.http.client.utils.URLEncodedUtils。
輸入org.apache.http.config.Registry。
輸入org.apache.http.config.RegistryBuilder。
輸入org.apache.http.conn.socket.ConnectionSocketFactory; 
輸入org.apache.http.conn.socket.PlainConnectionSocketFactory; 
輸入org.apache.http.conn.ssl.NoopH​​ostnameVerifier; 
輸入org.apache.http.conn.ssl.SSLConnectionSocketFactory; 
輸入org.apache.http.entity.StringEntity。
輸入org.apache.http.impl.client.CloseableHttpClient。
輸入org.apache.http.impl.client.HttpClients。
輸入org.apache.http.impl.conn.PoolingHttpClientConnectionManager。
輸入org.apache.http.message.BasicNameValuePair; 
輸入org.apache.http.ssl.SSLContextBuilder。
輸入org.apache.http.ssl.TrustStrategy。
輸入org.apache.http.util.EntityUtils。
輸入org.slf4j.Logger。
輸入org.slf4j.LoggerFactory;
 
インポートjavax.net.ssl.SSLContext; 
インポートjava.nio.charset.StandardCharsets; 
インポートjava.security.cert.CertificateException; 
はjava.security.cert.X509Certificateのインポート; 
java.util.ArrayListの輸入。
java.util.Listのインポート、
インポートjava.util.Map; 
インポートjava.util.Objects; 
インポートjava.util.stream.Collectors; 

/ ** 
 *のHttpクライアントの接続プールとツール。次の特性を有している
 * <OL> 
 </ LI>; * <LI> {@link org.apache.http.client.HttpClient} Apacheベースの性能HTTPクライアント
 * <LI>デフォルトの接続プールの最大数20、システム変数で指定され= 200 -Dzzarch.common.http.max.totalでき; </ LI> 
 * <LI>接続プールのデフォルトルーティングシステムが-Dzzarch.commonにより可変とすることができる、2当たりの最大接続数.http.max.per.route = 10を指定します。</ LI> 
 * <李>
 * <LI>可重试、通过{@link HttpOptions}进行设置</ LI> 
 * @authorのduyunjie 
 * @date 2019年9月18日午後04時33分
 * / 
publicクラスHttpClientUtil { 
    プライベート静的最終ロガーロガー= LoggerFactory。 getLogger(HttpClientUtil.class)。

    / ** 
     * HttpClientを连接池
     * / 
    プライベート静的PoolingHttpClientConnectionManager CONNECTION_MANAGER = initPoolingHttpClientConnectionManager(); 

    公共の静的な文字列HTTPGET(文字列のURL){例外をスロー
        (URL、NULL、NULL、NULL)HTTPGETを返します。
    } 


    公共の静的な文字列HTTPGET(文字列のURL、HttpOptions httpOptionsが){例外をスロー
        リターンHTTPGET(URL、NULL、NULL、httpOptions)。
    }


    公共の静的な文字列HTTPGET(文字列のURL、地図<?文字列、> paramsが){例外がスローされます
        (URLは、null、パラメータ、ヌル)HTTPGETを返します。
    } 


    公共の静的な文字列HTTPGET(文字列のURL、地図<?文字列> paramsは、HttpOptions httpOptions){例外をスロー
        (URL、ヌル、paramsは、httpOptions)HTTPGETを返します。
    } 


    公共の静的な文字列HTTPGETは(<?文字列>文字列のURLマップヘッダーマップ<?文字列>のparams){例外をスローする
        (ヌルURL、ヘッダ、paramsは、)HTTPGETを返します。
    } 

    / ** 
     *发送HTTP GET请求
     * 
     * @paramのURL 
     * @paramヘッダ请求头
     * @paramのparams请求参数 
     そのような再試行の回数、タイムアウト時間として* @param httpOptions構成パラメータ、。
     * @return
     @throws例外* 
     * / 
    パブリック静的な文字列HTTPGET(文字列のURL、地図<文字列、?>ヘッダ、地図<文字列、?>のparams、httpOptions httpOptionsザ・)スロー例外{ 
        //ロード要求アドレスとパラメータ
        URIBuilderのUB =新しいURIBuilder() ; 
        ub.setPath(URL); 

        //リクエストパラメータを変換し
        、リスト<NameValuePairsの> = convertParams2NVPSペア(のparams)
        IF {(pairs.isEmpty()!)
            ub.setParameters(ペア); 
        } 
        HTTPGET HTTPGET =新新HTTPGET(UB。 ())を構築; 

        //設定要求ヘッダ
        IF(Objects.nonNull(ヘッダ)){ 
        } 
            ため(ののMap.Entry <文字列、?> PARAM:headers.entrySet()){
                httpGet.addHeader(param.getKey()、String.valueOf(param.getValue()))。
            } 

        (HTTPGET、httpOptions)doHttpを返します。
    } 


    公共の静的な文字列httpPost(文字列のURLは、地図<?文字列>のparams)は例外{スロー
        (ヌル、URL、ヌル、paramsは)httpPostを返します。
    } 

    公共の静的な文字列httpPost(文字列のURL、地図<?文字列> paramsは、HttpOptions httpOptions){例外をスロー
        (URL、ヌル、paramsは、httpOptions)httpPostを返します。
    } 


    公共の静的な文字列httpPostは(<?文字列>文字列のURLマップヘッダーマップ<?文字列>のparams){例外をスローする
        (ヌルURL、ヘッダ、paramsは、)httpPostを返します。
    } 

    / ** 
     *发送HTTP POST请求
     * 
     * @paramのURL 
     * @paramヘッダ请求头
     * @paramのparams请求参数 
     などの再試行回数、タイムアウト時間として* @param httpOptions設定パラメータ、。
     @return * 
     * @throws例外
     * / 
    パブリック静的文字列HttpPost(<?文字列、>文字列のURL、地図ヘッダは、地図<?文字列>のparams、httpOptions httpOptionsザ・は){例外がスローされます
        HttpPost HttpPost =新新HttpPost(URL); 

        //変換要求パラメータ
        リスト<NameValuePairsの> = convertParams2NVPS対(paramsは); 
        もし{(!pairs.isEmpty())
            httpPost.setEntity(新しい新しいUrlEncodedFormEntity(ペア、StandardCharsets.UTF_8.name())); 
        } 

        //要求ヘッダーを設定
        する場合(Objects.nonNull(ヘッダ)){ 
            用の(のMap.Entry <?文字列> PARAM:headers.entrySet()){ 
                httpPost.addHeader(param.getKey()、String.valueOf(param.getValue()))。 
            } 
        } 

        doHttpリターン(httpOptions HttpPost); 
    } 


    / ** 
     *送信されたHTTP POSTリクエスト、フォーマットJSONで
     * <P>リクエストパラメータがJSONでありますフォーマット、データが符号化されている。8 UTF </ P> 
     * 
     * @paramのURL 
     * @param用のparam 
     *の@return 
     *例外@throws 
     * / 
    パブリック静的文字列httpPostJson(URL文字列、文字列PARAM、httpOptions httpOptionsザ)は例外{スロー
        HttpPost HttpPost =をHttpPost新新(URL); 

        //設定リクエストヘッダ
        httpPost.addHeader( "Content-Typeの"、 "ファイルアプリケーション/ JSON;のcharset = UTF-8"); 

        //リクエストパラメータを設定します
        httpPost.setEntity(新しい新しいStringEntity(PARAM、StandardCharsets.UTF_8.name())); 

        doHttp(HttpPost、httpOptions)を返す; 
    } 

    / ** 
     *送信されたHTTP POSTリクエスト、フォーマットXMLで
     * <P>リクエストパラメータは、XML形式であります8データエンコーディングがUTFである</ P> 
     * 
     * @paramのURL 
     * @param用のparam 
     *の@return 
     *例外@throws 
     * / 
    パブリック静的文字列httpPostXml(URL文字列、文字列PARAM、httpOptions httpOptionsザが){例外をスロー
        HttpPost HttpPost =新しい新しいHttpPost (URL); 

        //設定リクエストヘッダ
        httpPost.addHeader( "コンテンツタイプ"、 "ファイルアプリケーション/ XML;のcharset = UTF-8"); 

        //設定要求パラメータ
        httpPost.setEntity(新しい新しいStringEntity(PARAM、StandardCharsets.UTF_8.name())); 

        doHttp(HttpPost、httpOptions)を返す; 
    } 

 
    / **
     *変換要求パラメータ、キーと値のペアは、地図のQueryString列をステッチ
     * 
     * paramsはを@param 
     * @戻る
     * / 
    パブリック静的文字列convertParams2QueryStr(MAP <文字列、?>のparams){ 
        リスト<NameValuePairsの> = convertParams2NVPS対(paramsは); 

        URLEncodedUtils.format(ペア、StandardCharsets.UTF_8.name())を返す; 
    } 

    / ** 
     *変換をリクエストパラメータ
     * 
     * @param paramsは
     * @return 
     * / 
    パブリック静的リスト<のNameValuePair> convertParams2NVPS(地図<文字列、?>のparams){
        (paramsは== NULL){IF 
            のArrayList <>(新しい新を返す); 
        } 

        params.entrySet()ストリーム()地図(PARAM返す- >新しい新しいBasicNameValuePair(param.getKey()、String.valueOf(param.getValueを(.. 。))))を収集(Collectors.toList()); 
    } 

    / ** 
        //設定されたタイムアウト
     *发送HTTP请求
     * 
     * @param要求
     * @return 
     * @throws例外
     * / 
    プライベート静的な文字列doHttp(HttpRequestBase要求、HttpOptions httpOptions)例外{スロー
        IF(Objects.isNull(httpOptions)){//如果为空、则用の。默认的
            httpOptions =新しいhttpOptions()。
        } 
        IF(Objects.nonNull(httpOptions.getTimeoutMs())){ 
            request.setConfig(RequestConfig.custom()setSocketTimeout(httpOptions.getTimeoutMs())を作成()); 
        } 

        //设置重试策略
        HttpRequestRetryHandler httpRequestRetryHandler = NULL; 
        IF(Objects.nonNull(httpOptions.getRetryCount())){ 
            httpRequestRetryHandler =新しいHttpRequestRetryHandlerを( httpOptions.getRetryCount()); 
        } 

        //接続プールによって取得されたオブジェクト
        ;.)CloseableHttpClientのHttpClient = HttpClients.custom()setConnectionManager(CONNECTION_MANAGER).setRetryHandler(httpRequestRetryHandler).build(
        doRequest(HttpClientを、Request)を返します; 

    } 

    / * * 
     *処理HTTP / HTTPSリクエスト、リクエストの結果を返し
     * <P>注:デフォルト要求8エンコードUTF </ P> 
     * 
     * @paramのHttpClient 
     * @param要求を
     @return * 
     * @throws例外
     * /  
    プライベート静的doRequest文字列(のHttpClient CloseableHttpClient、HttpRequestBaseリクエスト)例外{スロー
        文字列結果= NULLと、
        CloseableHttpResponseレスポンス= NULL; 

        試み{ 
            //リクエストの結果がGET 
            応答= httpClient.execute(要求); 
            //解決要求が発生
            HttpEntityエンティティresponse.getEntity =を(); 
            //変換結果
            結果= EntityUtils.toString(エンティティ、StandardCharsets.UTF_8.name()); 
            //閉じるIOストリーム
            EntityUtils.consume(エンティティ); 
        }最後に{ 
            IF {(ヌル=レスポンス!)
                response.close(); 
            } 
        } 

        リターン結果; 
    } 


    / ** 
     *接続プールを初期化する
     * 
     * @return 
     * /
    静的PoolingHttpClientConnectionManager initPoolingHttpClientConnectionManagerプライベート(){ 
        // HTTP / HTTPS(すべての信頼できる証明書)を要求するために使用することができる接続プールを初期化
        PoolingHttpClientConnectionManagerのConnectionManager =新しい新しいPoolingHttpClientConnectionManager(getRegistryの()); 

        接続プールの全体の接続//最大数
        文字列maxTotal =はSystem.getProperty (Constants.SYSTEM_PROPERTY_KEY_HTTP_MAX_TOTAL); 
        IF(Objects.nonNull(maxTotal)){ 
            connectionManager.setMaxTotal(Integer.valueOf(maxTotal)); 
        } 

        //各経路の接続の最大数
        文字列maxPerRoute =はSystem.getProperty(Constants.SYSTEM_PROPERTY_KEY_HTTP_MAX_PER_ROUTE)。 
        IF(Objects.nonNull(maxPerRoute)){
            connectionManager.setDefaultMaxPerRoute(Integer.valueOf(maxPerRoute))。
        } 

        logger.info( "[ZZARCH_COMMON_SUCCESS_initPoolingHttpClientConnectionManager] maxTotal = {}、maxPerRoute = {}"、maxTotal、maxPerRoute)。
        ConnectionManagerを返します。
    } 


    / ** 
     *获取HTTPClientの注册器
     * 
     * @return 
     *は例外@throws 
     * / 
    プライベート静的レジストリを<ConnectionSocketFactory> getRegistryの(){ 
        {しようと
            RegistryBuilderを返します。<ConnectionSocketFactory>()を作成します。( "HTTP"(新PlainConnectionSocketFactoryを登録。))レジスタ( "HTTPS"、getSSLFactory())()を構築します。
        }キャッチ(例外e){
            logger.error( "[ERROR_getRegistry]"、E)。
        } 

        はnullを返します。
 
     *取得HTTPS SSL接続ファクトリー
     * <P>証明書の検証をスキップし、すなわち、すべての証明書を信頼</ P> 
     * 
     * @return 
     *は、例外を@throws 
     * / 
    プライベート静的SSLConnectionSocketFactory getSSLFactory()例外{スロー
        //設定HTTPS SSL証明書情報、証明書の検証がスキップされ、すなわち、すべての証明書要求HTTPS信頼
        )SSLContextBuilder sslBuilder新しい新しいSSLContextBuilder =を(。loadTrustMaterial(ヌル、新しい新TrustStrategy(){ 
            @Override 
            ブールIsTrusted公開(X509Certificateの[]カテナalberghiera、認証タイプ文字列)CertificateExceptionスロー{ 
                trueにリターン; 
            } 
        })。

        // SSL証明書HTTPS接続コンテキストを取得
        するSSLContext sslBuilder.buildのSSLContext =を(); 

        // GET HTTPS接続ファクトリ
        SSLConnectionSocketFactory sslCsf =新しいSSLConnectionSocketFactory(SSLContextの、新しいString [] { "でSSLv2Hello"、 "のSSLv3"、 "TLSv1の"、 "TLSv1.2"}、ヌル、NoopH​​ostnameVerifier.INSTANCE)。
        sslCsfを返します。
    } 


}

  

終わり

 

おすすめ

転載: www.cnblogs.com/waterystone/p/11551280.html