如何使用Spring WebClient获取分块编码响应的Trailer头信息?
获取Spring WebClient分块响应中的Trailer头
要获取分块编码响应中的Trailer头,你需要直接操作ClientResponse对象,并且确保完全消费响应体后再读取Trailer(因为Trailer是在最后一个数据块之后发送的)。你的原有代码使用retrieve()会自动处理响应体但无法暴露ClientResponse,因此无法访问Trailer。
解决方案步骤
- 使用
exchangeToMono/exchangeToFlux替代retrieve(),获取ClientResponse实例 - 先完全消费响应体(即使响应体为空)
- 通过
ClientResponse.trailers()方法获取Trailer头
代码示例
首先可以定义一个记录类来封装响应结果和Trailer信息:
record ApiResponse(List<byte[]> body, String resultCode, String errorMessage) {}
然后修改WebClient调用逻辑:
ApiResponse apiResponse = webClient.get() .uri("https://apiwithtailerresponse.com") .exchangeToMono(clientResponse -> { // 先消费响应体(即使为空也要完成这一步) Mono<List<byte[]>> bodyMono = clientResponse.bodyToFlux(byte[].class).collectList(); // 消费完body后读取Trailer头 return bodyMono.flatMap(body -> { HttpHeaders trailerHeaders = clientResponse.trailers(); String result = trailerHeaders.getFirst("x-result"); String error = trailerHeaders.getFirst("x-error"); return Mono.just(new ApiResponse(body, result, error)); }); }) .block();
关键说明
- 必须消费响应体:分块编码的Trailer头紧跟在最后一个数据块之后,WebClient只有在读完所有响应体内容后,才能获取到Trailer头信息。
ClientResponse.trailers():该方法返回包含所有Trailer头的HttpHeaders对象,你可以用普通的头操作方法(如getFirst()、get())提取需要的值。- 大响应体优化:如果响应体很大,不需要收集到内存中,可以用
bodyToFlux(byte[].class).then()来消费响应体而不保存,再读取Trailer:
String errorMessage = webClient.get() .uri("https://apiwithtailerresponse.com") .exchangeToMono(clientResponse -> clientResponse.bodyToFlux(byte[].class) .then(Mono.defer(() -> Mono.just(clientResponse.trailers().getFirst("x-error")) )) ) .block();
内容的提问来源于stack exchange,提问作者Bernard Maassen
相关产品推荐
相关产品推荐

