Spring RestTemplate-如何启用请求/响应的完整调试/日志记录?

问题描述

仅为了完成示例ClientHttpRequestInterceptor以跟踪请求和响应的完整实现,请执行以下操作:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {

    final static Logger log = LoggerFactory.getLogger(LoggingRequestInterceptor.class);

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        traceRequest(request, body);
        ClientHttpResponse response = execution.execute(request, body);
        traceResponse(response);
        return response;
    }

    private void traceRequest(HttpRequest request, byte[] body) throws IOException {
        log.info("===========================request begin================================================");
        log.debug("URI         : {}", request.getURI());
        log.debug("Method      : {}", request.getMethod());
        log.debug("Headers     : {}", request.getHeaders() );
        log.debug("Request body: {}", new String(body, "UTF-8"));
        log.info("==========================request end================================================");
    }

    private void traceResponse(ClientHttpResponse response) throws IOException {
        StringBuilder inputStringBuilder = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"));
        String line = bufferedReader.readLine();
        while (line != null) {
            inputStringBuilder.append(line);
            inputStringBuilder.append('\n');
            line = bufferedReader.readLine();
        }
        log.info("============================response begin==========================================");
        log.debug("Status code  : {}", response.getStatusCode());
        log.debug("Status text  : {}", response.getStatusText());
        log.debug("Headers      : {}", response.getHeaders());
        log.debug("Response body: {}", inputStringBuilder.toString());
        log.info("=======================response end=================================================");
    }

}

然后RestTemplate使用BufferingClientHttpRequestFactory和实例化LoggingRequestInterceptor

RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new LoggingRequestInterceptor());
restTemplate.setInterceptors(interceptors);

BufferingClientHttpRequestFactory因为我们要在拦截器和初始调用代码中都使用响应主体,所以这是必需的。默认实现只允许读取一次响应主体。

解决方法

spring

我使用Spring RestTemplate已经有一段时间了,当我尝试调试它的请求和响应时,我总是碰壁。我基本上希望看到的是与打开“ verbose”选项时使用curl时看到的相同的东西。例如 :

curl -v http://twitter.com/statuses/public_timeline.rss

将同时显示已发送的数据和已接收的数据(包括标题,cookie等)。

我已经检查了一些相关的帖子,例如: 如何在Spring RestTemplate中记录响应? 但是我还没有解决这个问题。

一种方法是实际更改RestTemplate源代码并在其中添加一些额外的日志记录语句,但是我会发现这种方法确实是不得已的事情。应该有某种方式告诉Spring Web Client / RestTemplate以更友好的方式记录所有内容。

我的目标是能够使用以下代码来做到这一点:

restTemplate.put(“http://someurl",objectToPut,urlPathValues);
然后在日志文件或控制台中获取相同类型的调试信息(与curl相同)。我相信这对于使用Spring RestTemplate并有问题的任何人都是非常有用的。使用curl调试RestTemplate问题根本无法正常工作(在某些情况下)。

猜你在找的技术问答相关文章

如何检查配对的蓝牙设备是打印机还是扫描仪(Android)
是否允许实体正文进行HTTP DELETE请求?
如何将ZipInputStream转换为InputStream?
java.util.logging Java 8中的变量
PowerMockito.doReturn返回null
Java中的RESTful调用
Swing / Java:如何正确使用getText和setText字符串
特殊字符和重音字符
Android Studio中的ndk.dir错误
错误“找不到主类”