1.概述
RestTemplate是spring封装的restful请求的模板,它内部封装了常用的GET、POST、DELETE、PUT等请求方式,帮助开发者更快构建HTTP请求。传统的请求方式采用Apache的HttpClient,此种方式编写http请求时需要编写大量代码,比较繁琐。本文将从代码量、以及最大访问量对比HttpClient与RestTemplate请求封装的工具类。
2.基于HttpClient封装的工具类
2.1 GET请求
利用HttpClient来发送GET请求时,需要考虑请求头的构造,资源的回收与释放等,代码量较多且操作较为繁琐。下面是封装的一个关于GET请求的方法。
public static String sendGet(String url, String params) throws Exception {
logger.info("GET Request uri: {} params: {}", url, params);
HttpGet httpGet = null;
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
// 响应内容
String result = null;
try {
// 创建默认的httpClient实例.
httpClient = HttpClients.createDefault();
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.addParameter("params", params);
httpGet = new HttpGet(uriBuilder.build());
httpGet.setConfig(requestConfig);
// 执行请求
response = httpClient.execute(httpGet);
// 得到响应实例
HttpEntity entity = response.getEntity();
// 判断响应状态
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
result = EntityUtils.toString(entity, HttpClientUtil.ENCODE_UTF8);
EntityUtils.consume(entity);
}
logger.info("GET Request uri: {}, params: {}, status code: {}, result: {}", url, params, statusCode, result);
if (statusCode >= 300 || statusCode < 200) {
throw new Exception("Response code is " + statusCode);
}
} catch (Exception e) {
logger.error("GET Request uri: {}, params: {}, error: {}", url, params, e.getMessage());
throw e;
} finally {
try {
// 释放资源
if (response != null) {
response.close();
}
} catch (IOException e) {
logger.warn("释放HttpResponse资源失败");
}
}
return result;
}
2.2 POST请求
post请求与get请求类似,都需要构造消息头、获取返回结果以及考虑资源的回收等,代码与上述get请求类似,工具类如下:
public static String sendPost(String url, String bodyParams) throws Exception {
logger.info("POST Request uri: {} body: {}", url, bodyParams);
String result = null;
CloseableHttpResponse httpResponse = null;
HttpPost httpPost = null;
CloseableHttpClient closeableHttpClient = null;
try {
closeableHttpClient = HttpClientBuilder.create().build();
URIBuilder uriBuilder = new URIBuilder(url);
httpPost = new HttpPost(uriBuilder.build());
// 构造消息头
httpPost.setHeader("Content-type", "application/json; charset=utf-8");
StringEntity stringEntity = new StringEntity(bodyParams, HttpClientUtil.ENCODE_UTF8);
httpPost.setEntity(stringEntity);
httpPost.setConfig(requestConfig);
httpResponse = closeableHttpClient.execute(httpPost);
// 判断响应状态
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
HttpEntity entity = httpResponse.getEntity();
result = EntityUtils.toString(entity);
}
logger.info("POST Request uri: {}, body: {}, status code: {}, result: {}", url, bodyParams, statusCode, result);
if (statusCode >= 300 || statusCode < 200) {
throw new Exception("Response code is " + statusCode);
}
} catch (Exception e) {
logger.error("POST Request uri: {}, body: {}, error: {}", url, bodyParams, e.getMessage());
throw e;
} finally {
try {
if (httpResponse != null) {
httpResponse.close();
}
} catch (IOException e) {
logger.warn("释放HttpResponse资源失败");
}
}
return result;
}
2.3 DELETE请求
public static String sendDelete(String url, String params) throws Exception {
logger.info("DELETE Request uri: {} params: {}", url, params);
HttpDelete httpDelete = null;
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
// 响应内容
String result = null;
try {
// 创建默认的httpClient实例.
httpClient = HttpClients.createDefault();
URIBuilder uriBuilder = new URIBuilder(url);
uriBuilder.addParameter("params", params);
httpDelete = new HttpDelete(uriBuilder.build());
httpDelete.setConfig(requestConfig);
// 执行请求
response = httpClient.execute(httpDelete);
// 得到响应实例
HttpEntity entity = response.getEntity();
// 判断响应状态
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
result = EntityUtils.toString(entity, HttpClientUtil.ENCODE_UTF8);
EntityUtils.consume(entity);
}
logger.info("DELETE Request uri: {}, params: {}, status code: {}, result: {}", url, params, statusCode, result);
if (statusCode >= 300 || statusCode < 200) {
throw new Exception("Response code is " + statusCode);
}
} catch (Exception e) {
logger.error("DELETE Request uri: {}, params: {}, error: {}", url, params, e.getMessage());
throw e;
} finally {
try {
// 释放资源
if (response != null) {
response.close();
}
} catch (IOException e) {
logger.warn("释放HttpResponse资源失败");
}
}
return result;
}
2.4 PUT请求
public static String sendPut(String url, String bodyParams) throws Exception {
logger.info("PUT Request uri: {} params: {}", url, bodyParams);
HttpPut httpPut = null;
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
// 响应内容
String result = null;
try {
// 创建默认的httpClient实例.
httpClient = HttpClients.createDefault();
URIBuilder uriBuilder = new URIBuilder(url);
httpPut = new HttpPut(uriBuilder.build());
httpPut.setHeader("Content-type", "application/json; charset=utf-8");
StringEntity stringEntity = new StringEntity(bodyParams, HttpClientUtil.ENCODE_UTF8);
httpPut.setEntity(stringEntity);
httpPut.setConfig(requestConfig);
// 执行请求
response = httpClient.execute(httpPut);
// 得到响应实例
HttpEntity entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
if (HttpStatus.SC_OK == statusCode) {
result = EntityUtils.toString(entity, HttpClientUtil.ENCODE_UTF8);
EntityUtils.consume(entity);
}
logger.info("PUT Request uri: {}, body: {}, status code: {}, result: {}", url, bodyParams, statusCode, result);
// 判断响应状态
if (statusCode >= 300 || statusCode < 200) {
throw new Exception("Response code is " + statusCode);
}
} catch (Exception e) {
logger.error("PUT Request uri: {}, body: {}, error: {}", url, bodyParams, e.getMessage());
throw e;
} finally {
try {
// 释放资源
if (response != null) {
response.close();
}
} catch (IOException e) {
logger.warn("释放HttpResponse资源失败");
}
}
return result;
}
3.基于RestTemplate封装的工具类
3.1 GET请求
/**
* @Description: GET请求,参数形式params={"deviceNum":"","type":""}
* @Author Marin
* @Date 2020/11/4 15:05
*/
public String sendGet(String url,String params) throws Exception {
logger.info("GET Request uri: {} params: {}", url, params);
Map<String, Object> map = new HashMap<>();
map.put("params",params);
StringBuffer buffer = new StringBuffer(url);
buffer.append("?params={params}");
ResponseEntity<String> result = null;
int statusCode = 0;
try {
result = restTemplate.getForEntity(buffer.toString(),String.class,map);
statusCode = result.getStatusCode().value();
} catch (RestClientException e) {
logger.error("GET Request uri: {}, params: {}, error: {}", url, params, e.getMessage());
}
if (statusCode == HttpStatus.SC_OK) {
return result.getBody();
}
if (statusCode >= 300 || statusCode < 200) {
throw new Exception("Response code is " + statusCode);
}
return ResponseCreator.writeJsonErr(result.getStatusCode().toString());
}
3.2 POST请求
/**
* @Description: POST请求,参数放于body体中,格式为{"deviceNum":"","type":""}
* @Author Marin
* @Date 2020/11/4 15:17
*/
public String sendPost(String url,String params) throws Exception {
logger.info("Post Request uri: {}, params: {}", url, params);
ResponseEntity<String> result = null;
int statusCode = 0;
try {
result = restTemplate.postForEntity(url, params, String.class);
statusCode = result.getStatusCode().value();
} catch (RestClientException e) {
logger.error("POST Request uri: {}, params: {}, error: {}", url, params, e.getMessage());
}
if (statusCode == HttpStatus.SC_OK) {
return result.getBody();
}
if (statusCode >= 300 || statusCode < 200) {
throw new Exception("Response code is " + statusCode);
}
return ResponseCreator.writeJsonErr(result.getStatusCode().toString());
}
3.3 DELETE请求
/**
* @Description: DELETE请求,参数形式params={"deviceNum":"","type":""}
* @Author Marin
* @Date 2020/11/5 14:27
*/
public String sendDelete(String url,String params) throws Exception {
logger.info("DELETE Request uri: {} params: {}", url, params);
ResponseEntity<String> result = null;
HashMap<String,Object> map = new HashMap<>();
map.put("params",params);
StringBuffer buffer = new StringBuffer(url);
buffer.append("?params={params}");
int statusCode = 0;
try {
result = restTemplate.exchange(buffer.toString(), HttpMethod.DELETE, null, String.class, map);
statusCode = result.getStatusCode().value();
} catch (RestClientException e) {
logger.error("DELETE Request uri: {}, params: {}, error: {}", url, params, e.getMessage());
}
if (statusCode == HttpStatus.SC_OK) {
return result.getBody();
}
if (statusCode >= 300 || statusCode < 200) {
throw new Exception("Response code is " + statusCode);
}
return ResponseCreator.writeJsonErr(result.getStatusCode().toString());
}
3.4 PUT请求
/**
* @Description: PUT请求,参数放于body体中,格式为{"deviceNum":"","type":""}
* @Author Marin
* @Date 2020/11/5 14:38
*/
public String sendPut(String url,String params) throws Exception {
logger.info("PUT Request uri: {} params: {}", url, params);
ResponseEntity<String> result = null;
int statusCode = 0;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
// 发送请求
HttpEntity<String> entity = new HttpEntity<>(params, headers);
try {
result = restTemplate.exchange(url, HttpMethod.PUT, entity, String.class);;
statusCode = result.getStatusCode().value();
} catch (RestClientException e) {
logger.error("PUT Request uri: {}, params: {}, error: {}", url, params, e.getMessage());
}
if (statusCode == HttpStatus.SC_OK) {
return result.getBody();
}
if (statusCode >= 300 || statusCode < 200) {
throw new Exception("Response code is " + statusCode);
}
return ResponseCreator.writeJsonErr(result.getStatusCode().toString());
}
4.代码量对比与性能对比
4.1 代码量对比
利用apache的HttpClient封装的get、post、put、delete请求,都需要构造请求头、执行请求并得到返回结果、回收资源等,而利用RestTemplate类来进行工具类的封装,只需要关注请求的发送与结果的获取,资源回收这部分已被RestTemplate底层封装,不需要我们进行额外的操作,有效避免编写不必要的代码。
5.小结
1.RestTemplate底层支持多种方式发起请求,具体可以查看源码;
2.RestTemplate上层代码主要采用apache的httpClient,因为只是多进行了一层封装;
3.在性能上,因为两者上层相似,所以性能差距不大。