ClientHttpRequestInterceptor响应为空

ClientHttpRequestInterceptor响应为空

本文介绍了为什么我的自定义ClientHttpRequestInterceptor响应为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于自定义日志拦截器,我已经完成了以下操作

I have done the following for my custom logging interceptor

public class HttpLoggingInterceptor implements ClientHttpRequestInterceptor {
    private final static Logger log = LoggerFactory.getLogger(HttpLoggingInterceptor.class);

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

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

    }

    private void logResponse(ClientHttpResponse response) throws IOException {
        log.info("Response Status code : {}, Status text : {}, Headers : {}, Response body: {}", response.getStatusCode(), response.getStatusText(), response.getHeaders(), StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()));
    }
}

我将拦截器设置为restTemplate

And I am setting the intercepter to the restTemplate

   @Autowired
    public RestTemplate restTemplate;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        List<ClientHttpRequestInterceptor> clientHttpRequestInterceptors = new ArrayList<>();
        clientHttpRequestInterceptors.add(new HttpLoggingInterceptor());
//        clientHttpRequestInterceptors.addAll(restTemplate.getInterceptors());
        restTemplate.setInterceptors(clientHttpRequestInterceptors);
//        restTemplate.setInterceptors(Collections.singletonList(new HttpLoggingInterceptor()));
}

记录器正在正确地将响应打印到控制台,但是最后,响应以空返回给调用方.我无法调试并弄清楚.

The logger is printing the response properly to the console, But at the end the response is returned as empty to the caller. I am not able to debug and figure it out.

我发现StreamUtils.copyToString(response.getBody(), Charset.defaultCharset())正在读取输入流一次,并且不再将响应主体保存在其中(现在为空)

I have figured it out that the StreamUtils.copyToString(response.getBody(), Charset.defaultCharset()) is reading the input stream once and it is no more holding the response body in it (which is empty now)

还有其他人也面临相同的问题,并且有任何想法要复制InputStream而不从原始InputStream中读取它吗?

Anyone else also facing the same issue and has any idea of duplicating the InputStream without reading it from the original InputStream?

推荐答案

由于输入流只能使用一次,并且sun.net.www.protocol.http.HttpURLConnection$HttpInputStream没有可用的reset()mark(***)函数.

Since the input stream can be consumed only once and there is no reset() or mark(***) function available for sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.

只有一种方法可以通过以下方式创建restTemplate来多次读取响应.

There is only one way to read the response multiple time by creating the restTemplate in the following way.

@Bean
public RestTemplate getfxoWsClientRestTemplate(){
    RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()));
    restTemplate.setInterceptors(Collections.singletonList(new HttpLoggingInterceptor()));
    return  restTemplate;
}

LoggingIntercepter可以这样写

public class HttpLoggingInterceptor implements ClientHttpRequestInterceptor {

    private final static Logger logger = LoggerFactory.getLogger(HttpLoggingInterceptor.class);

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    logger.info("request method: {}, request URI: {}, request headers: {}, request body: {}",
            request.getMethod(), request.getURI(), request.getHeaders(), new String(body, Charset.forName("UTF-8")));

    ClientHttpResponse response = execution.execute(request, body);

    logger.info("response status code: {}, response headers: {}, response body: {}",
            response.getStatusCode(), response.getHeaders(), new String(ByteStreams.toByteArray(response.getBody()), Charset.forName("UTF-8")));

    return response;
}

}

这篇关于为什么我的自定义ClientHttpRequestInterceptor响应为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 17:50