Spring Boot 2.0迁移:如何从WebClient ClientResponse提取响应头与状态码
嘿,很高兴帮你搞定这个响应式迁移的问题!既然想全程保持非阻塞、不用block(),咱们完全可以通过ClientResponse的响应式操作链来实现需求——既过滤响应头,又根据状态码处理响应,同时把状态码、过滤后的头和响应体封装返回。
第一步:定义自定义响应封装类
首先咱们得有个类来装最终要返回的信息,把状态码、过滤后的响应头和响应体都包进去:
public class CustomApiResponse<T> { private HttpStatus statusCode; private HttpHeaders filteredHeaders; private T body; // 构造器、getter/setter 按需实现 public CustomApiResponse(HttpStatus statusCode, HttpHeaders filteredHeaders, T body) { this.statusCode = statusCode; this.filteredHeaders = filteredHeaders; this.body = body; } // 省略getter方法... }
第二步:响应式处理ClientResponse(核心逻辑)
咱们可以用exchange()方法直接拿到ClientResponse,然后通过响应式操作符分支处理不同状态码,同时过滤响应头:
// 假设你已经初始化好了WebClient实例 webClient.get() .uri("/your-target-api") .exchange() .flatMap(clientResponse -> { // 先处理状态码和过滤响应头 HttpStatus status = clientResponse.statusCode(); HttpHeaders filteredHeaders = filterDesiredHeaders(clientResponse.headers().asHttpHeaders()); // 根据状态码分支处理响应体 if (status.is2xxSuccessful()) { // 成功状态:解析响应体并封装 return clientResponse.bodyToMono(YourBodyDto.class) .map(body -> new CustomApiResponse<>(status, filteredHeaders, body)); } else if (status.is4xxClientError()) { // 客户端错误:可以解析错误响应体,或者返回默认错误信息 return clientResponse.bodyToMono(ErrorResponseDto.class) .map(errorBody -> new CustomApiResponse<>(status, filteredHeaders, errorBody)); } else { // 其他异常状态:抛出响应式错误,交给上层处理 return Mono.error(new RuntimeException("Unexpected API status: " + status.value())); } }); // 单独抽离响应头过滤方法,方便维护 private HttpHeaders filterDesiredHeaders(HttpHeaders originalHeaders) { HttpHeaders filtered = new HttpHeaders(); // 这里替换成你需要保留的响应头,比如只保留Content-Type、X-Request-Id这类 originalHeaders.entrySet().stream() .filter(entry -> List.of("Content-Type", "X-Request-Id").contains(entry.getKey())) .forEach(entry -> filtered.put(entry.getKey(), entry.getValue())); return filtered; }
关键细节说明
- 全程没有用
block(),所有操作都是响应式的,保持了Spring Reactive的非阻塞特性 - 响应头过滤通过Stream API灵活筛选,你可以根据业务需求随时调整要保留的头字段
- 状态码分支处理用
flatMap配合bodyToMono,保证响应体解析和结果封装都在响应式链里完成 - 错误状态可以根据实际需求定制:比如404返回空body,500返回固定错误信息等等
内容的提问来源于stack exchange,提问作者Renus11
相关产品推荐
相关产品推荐

