使用Spring-boot 1.5.10.RELEASE,我得到的response.body为空。
这是我如何使用 RestTemplate
RestTemplate restTemplate = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new LoggingRequestInterceptor());
restTemplate.setInterceptors(interceptors);
String url = "http://someurl/Commands";
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("cmd", "{"operation":"getSomeDetails"}}");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
System.out.println("This is always null: " + response.getBody());
虽然上面的程序总是打印空,以下侦听器打印有效的响应正文
public class LoggingRequestInterceptor implements ClientHttpRequestInterceptor {
final static Logger log = LoggerFactory.getLogger(LoggingRequestInterceptor.class);
@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
traceRequest(request, body);
ClientHttpResponse response = execution.execute(request, body);
traceResponse(response);
return response;
}
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.debug("============================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.debug("=======================response end=================================================");
}
}
虽然接受的答案有原因,但我相信解决方案也是必要的。
Spring 有一个 BufferingClientHttpRequestFactory,它充当 Rest 模板默认 SimpleClientHttpRequestFactory 的包装器。它可以在创建过程中传递给 Rest 模板。这会强制 Rest 模板使侦听器使用响应的副本,而不是销毁它。
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
RestTemplate restTemplate = new RestTemplate(factory);
源:http://objectpartners.com/2018/03/01/log-your-resttemplate-request-and-response-without-destroying-the-body/
你在traceResponse
中使用响应体; 那是你的问题。另外,请更新您的问题以使其具体;"所有最新"没有任何意义。今天的最新情况明天就不是这样了。
下面的代码将解决问题。
@Bean public RestTemplate restTemplate() {
final RestTemplate restTempate = new RestTemplate(new BufferingClientHttpRequestFactory(new
SimpleClientHttpRequestFactory()));
final List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(new LogHttpInterceptor());
restTempate.setInterceptors(interceptors);
return restTemplate;}
虽然日志拦截器如下所示
public class LogHttpInterceptor implements ClientHttpRequestInterceptor {
final static Logger log = LoggerFactory.getLogger(LogHttpInterceptor.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");
}
如果不起作用,请告诉我
经过一段时间的搜索,我尝试使用 HttpComponentsClientHttpRequestFactory(( 而不是 SimpleClientHttpRequestFactory((
ClientHttpRequestFactory factory = new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory());
这为我解决了问题。
像这样创建你的 RestTemplate
@Bean
public RestTemplate interceptedRestTemplate() {
RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(
new SimpleClientHttpRequestFactory()
));
restTemplate.setInterceptors(List.of(<i>your interceptor</i>));
return restTemplate;
}
为我工作。