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

问题描述

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

  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.http.HttpRequest;
  7. import org.springframework.http.client.ClientHttpRequestExecution;
  8. import org.springframework.http.client.ClientHttpRequestInterceptor;
  9. import org.springframework.http.client.ClientHttpResponse;
  10. public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {
  11. final static Logger log = LoggerFactory.getLogger(LoggingRequestInterceptor.class);
  12. @Override
  13. public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
  14. traceRequest(request, body);
  15. ClientHttpResponse response = execution.execute(request, body);
  16. traceResponse(response);
  17. return response;
  18. }
  19. private void traceRequest(HttpRequest request, byte[] body) throws IOException {
  20. log.info("===========================request begin================================================");
  21. log.debug("URI : {}", request.getURI());
  22. log.debug("Method : {}", request.getMethod());
  23. log.debug("Headers : {}", request.getHeaders() );
  24. log.debug("Request body: {}", new String(body, "UTF-8"));
  25. log.info("==========================request end================================================");
  26. }
  27. private void traceResponse(ClientHttpResponse response) throws IOException {
  28. StringBuilder inputStringBuilder = new StringBuilder();
  29. BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"));
  30. String line = bufferedReader.readLine();
  31. while (line != null) {
  32. inputStringBuilder.append(line);
  33. inputStringBuilder.append('\n');
  34. line = bufferedReader.readLine();
  35. }
  36. log.info("============================response begin==========================================");
  37. log.debug("Status code : {}", response.getStatusCode());
  38. log.debug("Status text : {}", response.getStatusText());
  39. log.debug("Headers : {}", response.getHeaders());
  40. log.debug("Response body: {}", inputStringBuilder.toString());
  41. log.info("=======================response end=================================================");
  42. }
  43. }

然后RestTemplate使用BufferingClientHttpRequestFactory和实例化LoggingRequestInterceptor

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

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

解决方法

spring

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

  1. 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错误
错误“找不到主类”