HttpClient 4.3.5 使用總結(jié)

一,前言

調(diào)用HTTP接口時(shí)經(jīng)常會(huì)使用Apache HttpClient進(jìn)行Http請(qǐng)求發(fā)送,平常只是簡單的使用,今天對(duì)具體的使用進(jìn)行了一個(gè)總結(jié),方便以后查詢,因?yàn)锳pache HttpClient每次版本升級(jí)API變動(dòng)都很大,這里使用的是以較新的版本:4.5.3

二,使用方法

(1)創(chuàng)建CloseableHttpClient
首先需要?jiǎng)?chuàng)建一個(gè)CloseableHttpClient,然后通過CloseableHttpClient進(jìn)行g(shù)et、post、put等請(qǐng)求方式的調(diào)用

//官網(wǎng)的示例
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("http://targethost/homepage");
CloseableHttpResponse response = httpclient.execute(httpGet);
try {
    System.out.println(response.getStatusLine());
    HttpEntity entity = response.getEntity();
    // do something useful with the response body
    // and ensure it is fully consumed
    EntityUtils.consume(entity);
} finally {
    response.close();
}

使用方法相對(duì)簡單,但是默認(rèn)情況下各種超時(shí)設(shè)置都為-1,即無限制,這樣會(huì)導(dǎo)致各種超時(shí)阻塞問題的發(fā)生,因此在線上的使用過程中應(yīng)該對(duì)一些常見的超時(shí)設(shè)置進(jìn)行自定義。
(2)超時(shí)設(shè)置
Appache HttpClient提供了一個(gè)配置類,用于請(qǐng)求的超時(shí)等其他配置

//HttpClient請(qǐng)求超時(shí)配置
RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT)
                    .setSocketTimeout(SOCKET_TIMEOUT)
                    .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                    .build();

源碼中的3個(gè)超時(shí)設(shè)置:
connectionRequestTimeout :從連接池中獲取可用連接的時(shí)間
connectTimeout :連接超時(shí)時(shí)間,客戶端請(qǐng)求服務(wù)器與服務(wù)器建立連接(三次握手)成功的最大接受時(shí)間
socketTimeout :請(qǐng)求獲取數(shù)據(jù)的超時(shí)時(shí)間,訪問一個(gè)接口指定時(shí)間內(nèi)無法返回?cái)?shù)據(jù),直接放棄此次調(diào)用

Builder() {
            super();
            this.staleConnectionCheckEnabled = false;
            this.redirectsEnabled = true;
            this.maxRedirects = 50;
            this.relativeRedirectsAllowed = true;
            this.authenticationEnabled = true;
            this.connectionRequestTimeout = -1;
            this.connectTimeout = -1;
            this.socketTimeout = -1;
            this.contentCompressionEnabled = true;
        }

可以看到源碼中默認(rèn)賦值為-1,這里可以通過上述RequestConfig 進(jìn)行配置。
(3)連接池配置
建立一次連接是需要耗費(fèi)一定時(shí)間與資源的,常見的方式是通過連接池來提高效率,Appache HttpClient也提供了相關(guān)的連接池配置:

PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(POOL_MAX_TOTAL);
connectionManager.setDefaultMaxPerRoute(POOL_MAX_PRE_ROUTE);

setMaxTotal()方法用來設(shè)置連接池的最大連接數(shù),即整個(gè)池子的大??;
setDefaultMaxPerRoute()方法來設(shè)置每一個(gè)路由的最大連接數(shù),這里的路由是指IP+PORT,例如連接池大小(MaxTotal)設(shè)置為300,路由連接數(shù)設(shè)置為200(DefaultMaxPerRoute),對(duì)于www.a.comwww.b.com兩個(gè)路由來說,發(fā)起服務(wù)的主機(jī)連接到每個(gè)路由的最大連接數(shù)(并發(fā)數(shù))不能超過200,兩個(gè)路由的總連接數(shù)不能超過300。
因此,最終我們可以這樣來獲取CloseableHttpClient:

httpClient = HttpClients.custom()
             .setDefaultRequestConfig(requestConfig)
             .setConnectionManager(connectionManager)
              .build();

(4)請(qǐng)求參數(shù)設(shè)置
實(shí)際情況中我們請(qǐng)求接口服務(wù)時(shí)參數(shù)比較多,可以通過HttpClient提供的方法來方便的構(gòu)建請(qǐng)求參數(shù):

//get參數(shù)拼接,url為請(qǐng)求接口地址
URIBuilder builder = new URIBuilder(url);
//通過setParameter來設(shè)置參數(shù)key-value
builder.setParameter("params-1", "value-1");
builder.setParameter("params-2", "value-2");
HttpGet httpGet = new HttpGet(builder.build());

//post方式參數(shù)構(gòu)造
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> values = new ArrayList<NameValuePair>();
values.add(new BasicNameValuePair("params-1", "value-1"));
values.add(new BasicNameValuePair("params-2", "value-2"));
httpPost.setEntity(new UrlEncodedFormEntity(values, "UTF-8"));

(5)返回結(jié)果處理

//這里以post為例
CloseableHttpResponse response = httpclient.execute(httpPost)
//消費(fèi)服務(wù)器響應(yīng)內(nèi)容
EntityUtils.toString(response.getEntity(), "UTF-8");

(6)連接釋放與關(guān)閉

//連接池關(guān)閉
CloseableHttpClient .close();
//下面兩個(gè)方法均可以釋放連接到連接池
EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(response.getEntity());

這里需要注意的時(shí),在使用連接池的情況下要慎用CloseableHttpClient .close(),因?yàn)樵摲椒〞?huì)關(guān)閉整個(gè)連接池,源碼如下:

List<Closeable> closeablesCopy = closeables != null ? new ArrayList<Closeable>(closeables) : null;
        if (!this.connManagerShared) {
            if (closeablesCopy == null) {
                closeablesCopy = new ArrayList<Closeable>(1);
            }
            //連接池管理類
            final HttpClientConnectionManager cm = connManagerCopy;
            if (evictExpiredConnections || evictIdleConnections) {
                final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(cm,
                        maxIdleTime > 0 ? maxIdleTime : 10, maxIdleTimeUnit != null ? maxIdleTimeUnit : TimeUnit.SECONDS);
                closeablesCopy.add(new Closeable() {
                    @Override
                    public void close() throws IOException {
                        connectionEvictor.shutdown();
                    }
                });
                connectionEvictor.start();
            }
            closeablesCopy.add(new Closeable() {
                @Override
                public void close() throws IOException {
                    //關(guān)閉連接池
                    cm.shutdown();
                }

            });
        }
        //最終使用的是InternalHttpClient執(zhí)行execute()方法
        return new InternalHttpClient(
                execChain,
                connManagerCopy,
                routePlannerCopy,
                cookieSpecRegistryCopy,
                authSchemeRegistryCopy,
                defaultCookieStore,
                defaultCredentialsProvider,
                defaultRequestConfig != null ? defaultRequestConfig : RequestConfig.DEFAULT,
                closeablesCopy);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,302評(píng)論 6 13
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,253評(píng)論 6 342
  • 傍晚,我們一家三口去山上打水。雨后的山上,空氣格外清新,久違的小草的味道沁人心脾,絲絲山風(fēng)也涼爽宜人,山路崎嶇不平...
    杭杭出狀元閱讀 248評(píng)論 0 3
  • 打卡
    霽月月月閱讀 368評(píng)論 1 1

友情鏈接更多精彩內(nèi)容