项目中经常会用到向第三方系统发送请求来传递数据或者获得信息,一般用的比较多的为HttpClient 和 HttpRequest,这里简要总结一下 HttpClient 和 HttpRequest 的用法
一、HttpClient
1. 发送get请求
public static String get(String url, Map<String, String> headMap, int timeout) {
String result = null;
CloseableHttpClient httpclient = HttpClients.createDefault();
CloseableHttpResponse response = null;
try {
HttpGet httpGet = new HttpGet(url);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout).build();
httpGet.setConfig(requestConfig);
setHead(httpGet, headMap);
response = httpclient.execute(httpGet);
HttpEntity entity = response.getEntity();
result = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity);
} catch (Exception e) {
LOG.error("HttpGet [{}] error: {}", url, e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
} finally {
try {
if (null != response) {
response.close();
}
httpclient.close();
} catch (IOException e) {
LOG.error("HttpGet [{}] httpclient close error: {}", url, e.getMessage(), e);
}
}
return result;
}
1. 发送post请求
public static String postJson(String url, String body, Map<String, String> headMap, int timeout) {
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
try {
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
setHead(httpPost, headMap);
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout).build();
httpPost.setConfig(requestConfig);
httpPost.setEntity(new StringEntity(body, "UTF-8"));
response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
String responseContent = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity);
return responseContent;
} catch (Exception e) {
LOG.error("HttpPostJson [{}] error: {}", url, e.getMessage(), e);
throw new RuntimeException(e.getMessage(), e);
} finally {
try {
response.close();
httpClient.close();
} catch (IOException e) {
LOG.error("HttpPostJson [{}] httpclient close error: {}", url, e.getMessage(), e);
}
}
}
private static void setHead(HttpRequestBase httpRequestBase, Map<String, String> headMap) {
if (headMap != null && headMap.size() > 0) {
Set<String> keySet = headMap.keySet();
for (String key : keySet) {
httpRequestBase.addHeader(key, headMap.get(key));
}
}
}
优点:连接池(复用HTTP连接)、重试、代理机制,社区活跃,性能更加优异
缺点:配置和API使用较为复杂
二、HttpRequest
1. 发送get请求
public static String get(String methodName, String url, Map<String, Object> paramMap, Map<String, String> headers){
return HttpRequest.get(url).addHeaders(headers).form(paramMap).execute().body();
}
2. 发送post请求
public static String postForm(String methodName, String url, Map<String, Object> paramMap, Map<String, String> headers, String paramStr){
return HttpRequest.post(url).addHeaders(headers).form(paramMap).body(paramStr).execute().body();
}
优点:功能简单,整体比较易用
缺点:性能一般,社区支持较弱
三、对比
hutool 的 HttpRequest 底层是基于 HttpClient 的,是对其进行了封装,提供了更加简便的API请求,使用 HttpRequest 可在一行代码中实现发送简单的HTTP请求,如果需要使用 HttpClient 更加复杂的操作,则可以通过自定义 HttpClient 并通过 setHttpClient() 方法传入 HttpClient
例如通过自定义Httpclient实现设置最大连接数量
// 创建连接池管理器
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(100); // 设置最大连接数
connectionManager.setDefaultMaxPerRoute(20); // 设置每个路由的最大连接数
// 创建自定义的HttpClient
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
.setConnectionManager(connectionManager);
// 使用 Hutool 的 HttpRequest 发送请求
HttpResponse response = HttpRequest.get("https://example.com")
.timeout(5000) // 设置超时时间
.setHttpClient(httpClientBuilder.build()) // 设置自定义的HttpClient
.execute();
总结:
- 小型简单项目可使用 HttpRequest 快速请求,较大型复杂项目适合使用 HttpClient
- HttpClient 引入 httpclient 依赖,HttpRequest 引入 hutool 依赖
- 如果有连接池、重试、代理等机制的需求则可使用 HttpClient
- 高性能,高并发,有复杂Http操作的场景则可使用 HttpClient