为什么我的自定义ClientHttpRequestInterceptor具有空响应

时间:2018-04-25 13:32:58

标签: spring interceptor resttemplate

我为自定义日志记录拦截器

做了以下操作
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()));
    }
}

我正在将intercepter设置为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()));
}

记录器正在将响应正确打印到控制台,但最后响应返回为调用者为空。我无法调试并弄明白。

我已经发现StreamUtils.copyToString(response.getBody(), Charset.defaultCharset())正在读取输入流一次并且它不再持有响应主体(现在为空)

其他人也面临同样的问题,并且想知道在没有从原始InputStream中读取它的情况下重复InputStream吗?

1 个答案:

答案 0 :(得分:3)

由于输入流只能被使用一次,import com.twilio.twiml.voice.Gather; import com.twilio.twiml.VoiceResponse; import com.twilio.twiml.voice.Say; import com.twilio.twiml.TwiMLException; public class Example { public static void main(String[] args) { Say say = new Say .Builder("Welcome to Twilio, please tell us why you're calling").build(); Gather gather = new Gather.Builder().input("speech") .action("/completed").say(say).build(); VoiceResponse response = new VoiceResponse.Builder().gather(gather) .build(); try { System.out.println(response.toXml()); } catch (TwiMLException e) { e.printStackTrace(); } } 没有reset()mark(***)功能。

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

sun.net.www.protocol.http.HttpURLConnection$HttpInputStream

@Bean public RestTemplate getfxoWsClientRestTemplate(){ RestTemplate restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory())); restTemplate.setInterceptors(Collections.singletonList(new HttpLoggingInterceptor())); return restTemplate; } 可以像这样写出

LoggingIntercepter

}