RestTemplate如何获取HTTP请求返回的原始响应字节数据
如何通过RestTemplate获取原始响应字节
默认使用RestTemplate调用接口时,返回的ResponseEntity<String>等泛型对象中,getBody()是经过HttpMessageConverter解析转换后的内容,getHeaders()是已经解析完成的响应头键值对,无法直接拿到未处理的原始字节块。可以根据自己的需求选择以下方案获取原始字节:
方案一:仅获取响应体原始字节
如果只需要响应体的原始字节,不需要未解析的原始响应头、响应行,最简单的方式是直接将exchange方法的响应类型参数指定为byte[].class,此时返回的body就是未经过字符编码等转换的原始响应体字节数组:
RestTemplate rt = new RestTemplate(); HttpEntity<String> he = new HttpEntity<>(output, hh); // 响应类型指定为byte数组 ResponseEntity<byte[]> re = rt.exchange("http://localhost:8080/my", HttpMethod.GET, he, byte[].class); // 直接拿到原始响应体字节 byte[] rawResponseBody = re.getBody(); // 解析后的响应头依然可以正常获取 HttpHeaders parsedHeaders = re.getHeaders();
这种方式不需要额外修改RestTemplate的配置,对原有逻辑侵入最小,能满足绝大多数只需要原始响应体的场景。
方案二:获取完整原始响应报文(含响应行、未解析响应头、响应体)
如果需要拿到HTTP响应整块的原始字节(包含最原始的响应状态行、未经过解析的响应头行、响应体),可以通过带缓存的请求工厂+拦截器的方式,在响应被消息转换器解析前读取完整的响应流:
// 初始化带缓存功能的请求工厂,避免响应流被读取后无法供后续转换逻辑使用 SimpleClientHttpRequestFactory baseFactory = new SimpleClientHttpRequestFactory(); BufferingClientHttpRequestFactory bufferingFactory = new BufferingClientHttpRequestFactory(baseFactory); RestTemplate rt = new RestTemplate(bufferingFactory); // 添加响应拦截器,在解析前读取原始字节 rt.getInterceptors().add((request, body, execution) -> { ClientHttpResponse response = execution.execute(request, body); // 读取响应体原始字节,如果需要完整HTTP报文,可自行拼接响应状态行、响应头的原始字节 byte[] rawFullResponse = StreamUtils.copyToByteArray(response.getBody()); // 可根据自己的业务逻辑存储原始字节,比如存入线程上下文、自定义响应包装类 return response; }); // 后续正常发起请求即可,不影响原有参数、响应的转换逻辑 HttpEntity<String> he = new HttpEntity<>(output, hh); ResponseEntity<String> re = rt.exchange("http://localhost:8080/my", HttpMethod.GET, he, String.class);
注意:
BufferingClientHttpRequestFactory会把整个响应内容缓存到内存中,不要在下载大文件等响应体过大的场景使用,避免触发内存溢出。
内容的提问来源于stack exchange,提问作者chris01
相关产品推荐
相关产品推荐

