繁体   English   中英

Spring Boot RestTemplate ClientHttpRequestInterceptor 记录异常情况下的响应体

[英]Spring Boot RestTemplate ClientHttpRequestInterceptor log response body in case of exception

我正在使用 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: Unrecognized field "items" (class com.exapmle.group.web.beans.Response), not marked as ignorable (3 known properties: "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)

这是个老问题,我还是会回答,以防万一有人在看。 如果出现带有 http 代码(例如 500)的 API 错误,我可以通过以下配置获得响应。

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {

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

        RestTemplate restTemplate = new RestTemplate(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];
    }

这应该工作:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM