Spring Boot RestTemplate 的 ClientHttpRequestInterceptor 在出现异常时记录响应体。

4

我正在使用一个ClientHttpRequestInterceptor来报告RestTemplate的请求和响应。如果模板试图使用错误的类反编组响应,则需要记录异常情况下的响应。

以下是拦截器的启用方式:

@Bean
public RestTemplate restTemplate(ReportingConfiguration reportingConfiguration) {
    return new RestTemplateBuilder()
            .interceptors(new RestTemplateInterceptor())
            .build();
}

这里只接受ClientHttpRequestInterceptor接口。 拦截器看起来像这样:
@Override
public ClientHttpResponse intercept(HttpRequest req, byte[] body, ClientHttpRequestExecution execution) throws IOException {

    ...

    ClientHttpResponse response = null;
    try {
        response = execution.execute(request, body);
    } catch (Exception e) {
        System.out.println("I need to get the response here");
    }

    ...

我知道使用这个类是无法获取响应的,能否提供一种替代方案?

以下是异常示例:(请不要解释如何消除此异常,我知道为什么会出现这种情况,但我想在发生这种情况时记录有效负载)

Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: 未识别字段“items”(类com.exapmle.group.web.beans.Response),没有标记为可忽略的(已知属性有:“text”,“status”,“set-cookies”) at [Source: (ByteArrayInputStream); line: 1, column: 11] (through reference chain: com.exapmle.group.web.beans.Response["items"]) at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61) at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823) at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1153) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589) at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)


你能提供更多的代码和堆栈跟踪吗? - Samuel
请查看此链接 - adarshr
2个回答

0

这是一个旧问题,但我仍然会回答,以防有人正在寻找答案。在API错误和HTTP代码(如500)的情况下,我可以通过以下配置获取响应。

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {

        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(5000);
        factory.setReadTimeout(5000); 

        RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(factory));
        restTemplate.setInterceptors(Collections.singletonList(new CustomLoggingRequestInterceptor()));

        return restTemplate;
    }

现在是关于日志拦截器的部分。

    @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 traceResponse(ClientHttpResponse response) throws IOException {
        StringBuilder inputStringBuilder = new StringBuilder();

        inputStringBuilder.append(new String(getResponseBody(response), StandardCharsets.UTF_8));
         log.error(inputStringBuilder.toString()); 
      }
   
    protected byte[] getResponseBody(ClientHttpResponse response) {
        try {
            return FileCopyUtils.copyToByteArray(response.getBody());
        } catch (IOException ex) {
            // ignore
        }
        return new byte[0];
    }

执行 execution.execute(request, body); 时抛出异常,因此 traceResponse(response); 没有被执行。 - DeejonZ

-2

这应该可以工作:

ClientHttpResponse response = null;
try {
    response = execution.execute(request, body);
} catch (Exception e) {
    System.out.println("I need to get the response here", e.getMessage());
}

这样我只能看到异常而无法看到有效载荷。 - DeejonZ
你具体遇到了什么异常?能否请您将其发布出来。 - Ganesh chaitanya
你是什么意思? - DeejonZ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接