给RestTemplate添加拦截器记录请求响应

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情

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;
    }
复制代码

猜你喜欢

转载自juejin.im/post/7127850581271511048