實現方法
使用HttpClient發送請求、接收響應很簡單,一般需要如下幾步即可。
1. 創建HttpClient對象。
2. 創建請求方法的實例:HttpGet對象或HttpPost,並指定請求URL。
3. 設置配置參數,通過RequestConfig可以配置連接超時時間、Socket超時時間等重要參數
4. 設置請求參數,HttpGet、HttpPost使用setParams(HttpParams params)添加請求參數;HttpPost還可用setEntity(HttpEntity entity)方法來添加請求參數。
5. 調用HttpClient.execute(HttpUriRequest request)發送請求,響應結果封裝於HttpResponse。
6. HttpResponse.getAllHeaders()、getHeaders(String name)方法可獲取響應頭;HttpResponse.getEntity()可獲取響應結果;HttpResponse.getStatusLine可獲取響應狀態碼
7. 將字節流轉換成字符串
8. 釋放http連接(重要)
POST方法重要部分說明
- 通過costTime記錄請求響應具體時間,方便後續監控執行時間
- 通過service字段記錄此方法調用方,通過記錄日誌可以統計調用方qps
- 異常細化處理,該方法可捕捉ConnectTimeoutException、 SocketTimeoutException異常,正對此類異常可以專門監控統計(此類異常出現,要麼是網絡抖動,要麼是對方服務宕機,會導致嚴重後果,需要特殊處理)
代碼
public static String doPost(String service,String url, Map<String, String> params,Map<String,String> headers,int timeout) {
//通過service字段,打印日誌, 方便統計qps
logger.info("begin http call service={},method={},url={}",service,"post",url);
CloseableHttpClient httpclient = null;
CloseableHttpResponse response = null;
//記錄請求響應時間
long costTime = 0;
String result = null;
try {
long start = System.currentTimeMillis();
//1、創建HttpClient
httpclient = HttpClients.createDefault();
//2、指定URL創建HttpPost
HttpPost httpPost = new HttpPost(url);
//3、設置配置:連接超時時間和Socket超時時間
RequestConfig config = RequestConfig.custom().setConnectTimeout(timeout).setSocketTimeout(timeout).build();
httpPost.setConfig(config);
//4、設置請求參數
List<NameValuePair> nvps = new ArrayList<>();
if(params != null && params.keySet().size() > 0) {
for(Map.Entry<String, String> entry : params.entrySet()) {
nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
}
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
//4、設置請求Headers
if (headers != null && headers.keySet().size() > 0) {
for (Map.Entry<String, String> entry : headers.entrySet()) {
httpPost.setHeader(entry.getKey(),entry.getValue());
}
}
//5、執行POST方法,獲取響應結果
response = httpclient.execute(httpPost);
//6、獲取響應狀態碼
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() != 200) {
logger.info("[doPost]request url:{} post params :{} statusCode:{} ", url, params, statusLine.getStatusCode());
return null;
}
//6、獲取響應內容
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
//7、將字節流轉換成字符串
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
is.close();
reader.close();
result = sb.toString();
EntityUtils.consume(entity);
long end = System.currentTimeMillis();
costTime = end - start;
return result;
} catch (ConnectTimeoutException e) {
//連接超時異常需專門監控
logger.warn("[doPost]Connect timed out service={},url={},params={},exception={}",service, url, params, e);
return null;
} catch (SocketTimeoutException e) {
//Socket讀異常需專門監控
logger.warn("[doPost]Read timed out service={},url={} params={} exception={}",service, url, params, e);
return null;
}
catch (Exception e) {
logger.warn("[doPost]request service={},url={} params={} exception={}",service, url, params, e);
return null;
} finally {
//8、釋放連接
try {
if(response != null) {
response.close();
}
if(httpclient != null) {
httpclient.close();
} catch (IOException e) {
logger.warn("[doPost]request url:{} params :{} close response exception", url, params);
}
logger.info("end http call service={},costTime={},method={},url={},params={},result={}", service, costTime, "post", url, params, result);
}
}