实现方法
使用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);
}
}