RestTemplate概述
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
引入依赖:
使用RestTemplate需要引入spring-boot-starter-web;
- 使用maven引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.12.RELEASE</version>
</dependency>
- 使用gradle:
compile 'org.springframework.boot:spring-boot-starter-web'
使用时可以在配置代码中实例化bean
添加配置注解:
@Configuration
@ConditionalOnWebApplication
public class CommonWebConfiguration {
}
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
简单使用RestTemplate:
执行Get请求
URI uri = UriComponentsBuilder.fromUriString(uriStr) //
.queryParam("token", token) //
.queryParam("id",id)
.build().encode().toUri();
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
ResponseEntity<String> responseEntity = restTemplate.exchange(uri, HttpMethod.GET, requestEntity,
String.class);
给RestTemplate添加拦截器
有时候在对接调试时,经常需要记录一下接口请求和响应的数据;便于调试查找问题,这时可以通过拦截器,记录下请求响应信息;
- 定义拦截器,继承ClientHttpRequestInterceptor
重写一下intercept方法
public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
public static Logger logger = LoggerFactory.getLogger(RestTemplateInterceptor.class);
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest,bytes);
return response;
}
}
- 记录请求和响应信息的方法:
记录信息::
请求地址,请求方法,请求header,body,
响应状态码,header body等
//记录请求
private void recordRequest(HttpRequest httpRequest, byte[] bytes){
logger.debug("请求地址:{},请求方法:{}",httpRequest.getURI(),httpRequest.getMethodValue());
logger.debug("请求header:{}",httpRequest.getHeaders());
logger.debug("请求body:{}",new String(bytes, StandardCharsets.UTF_8));
logger.debug("请求开始---------------------------------");
}
public void recordResponse(ClientHttpResponse response) throws IOException{
StringBuilder inputStringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(response.getBody(),StandardCharsets.UTF_8));
String line = bufferedReader.readLine();
while (line!=null){
inputStringBuilder.append(line).append("\n");
line = bufferedReader.readLine();
}
logger.debug("Status code : [{}]", response.getStatusCode());
logger.debug("Status text : [{}]", response.getStatusText());
logger.debug("Headers : [{}]", response.getHeaders());
logger.debug("Response body: [{}]", inputStringBuilder);
}
- 除了可以记录信息,还可以给请求加点东西:
//给请求加点东西
private void handlerRequest(HttpRequest request){
HttpHeaders headers = request.getHeaders();
headers.add("my_key","my_value");
}
- 将记录的方法添加到intercept中:
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
handlerRequest(httpRequest);
recordRequest(httpRequest,bytes);
ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest,bytes);
recordResponse(response);
return response;
}
- 给RestTemplate配置一下拦截器;
可以再配置文件中,实例化一下bean
@Bean
public RestTemplateInterceptor restTemplateInterceptor(){
return new RestTemplateInterceptor();
}
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
//restTemplate.getInterceptors().add(restTemplateInterceptor());
return restTemplate;
}
- 发起请求,输出响应和请求数据;
有个问题
在RestTemplate测试时,发现没有响应信息,后来发现是,输出流只读一次的问题;
解决这个问题:
解决这个问题可以使用:BufferingClientHttpRequestFactory
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
BufferingClientHttpRequestFactory simpleBufferingClientHttpRequest =
new BufferingClientHttpRequestFactory(requestFactory);
requestFactory.setConnectTimeout(5000);
requestFactory.setReadTimeout(3500);
RestTemplate restTemplate = new RestTemplate(simpleBufferingClientHttpRequest);
restTemplate.getInterceptors().add(restTemplateInterceptor());
return restTemplate;
}