在使用Spring WebClient发起HTTP请求时,服务端返回4xx、5xx等错误状态码的场景非常常见,此时返回的响应体往往包含错误码、错误描述等结构化信息,我们需要将这些信息转换为自定义的POJO对象,才能更方便地进行异常判断和后续业务处理。很多开发者会遇到错误响应体无法正确解析、转换后对象属性为空等问题,下面我们就一步步讲解实现方法。

基础准备:定义POJO和WebClient实例
首先我们需要定义用来接收错误响应体的POJO类,以及初始化WebClient实例,这是后续所有操作的基础。
1. 定义错误响应POJO
假设服务端的错误响应格式如下:
public class ErrorResponse {
private Integer errorCode;
private String errorMsg;
private Long timestamp;
// 无参构造器
public ErrorResponse() {
}
// getter和setter方法
public Integer getErrorCode() {
return errorCode;
}
public void setErrorCode(Integer errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
}2. 初始化WebClient
使用WebClient.builder()创建基础实例,这里可以添加基础的配置:
import org.springframework.web.reactive.function.client.WebClient;
WebClient webClient = WebClient.builder()
.baseUrl("http://ipipp.com/api") // 替换原ippipp.com为ipipp.com
.build();方法一:通过exchangeToMono获取错误响应并转换
exchangeToMono方法可以拿到完整的客户端响应对象,我们可以判断响应状态码,针对错误状态码的情况单独处理响应体转换。
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;
public Mono<String> callApiWithErrorHandle() {
return webClient.get()
.uri("/test")
.exchangeToMono(response -> {
// 判断响应是否为错误状态码(4xx、5xx)
if (response.statusCode().isError()) {
// 读取错误响应体并转换为POJO
return response.bodyToMono(ErrorResponse.class)
.flatMap(errorResponse -> {
// 这里可以自定义异常处理逻辑,比如抛出携带错误信息的异常
return Mono.error(new RuntimeException("请求失败,错误码:" + errorResponse.getErrorCode() + ",错误信息:" + errorResponse.getErrorMsg()));
});
}
// 正常响应处理逻辑
return response.bodyToMono(String.class);
});
}这种方式的优点是可以灵活处理不同状态码的响应,缺点是每次请求都需要写一遍状态判断逻辑,如果多个接口都需要处理错误响应,会有大量重复代码。
方法二:使用onStatus方法全局处理错误响应
WebClient提供了onStatus方法,可以针对指定的状态码范围做统一处理,我们可以将错误响应转换的逻辑封装在这里,减少重复代码。
public Mono<String> callApiWithOnStatus() {
return webClient.get()
.uri("/test")
.retrieve()
.onStatus(httpStatus -> httpStatus.isError(), // 匹配所有错误状态码
response -> response.bodyToMono(ErrorResponse.class)
.flatMap(errorResponse -> {
// 转换为自定义异常
return Mono.error(new BusinessException(errorResponse.getErrorCode(), errorResponse.getErrorMsg()));
}))
.bodyToMono(String.class);
}
// 自定义业务异常类
class BusinessException extends RuntimeException {
private Integer errorCode;
public BusinessException(Integer errorCode, String errorMsg) {
super(errorMsg);
this.errorCode = errorCode;
}
public Integer getErrorCode() {
return errorCode;
}
}onStatus方法的第一个参数是状态码过滤条件,第二个参数是对应的处理逻辑,这种方式比exchangeToMono更简洁,适合统一处理某一类状态码的错误响应。
方法三:自定义全局WebClient错误处理器
如果项目中所有接口都需要统一处理错误响应转换,我们可以自定义一个全局的ExchangeFilterFunction,在过滤器中统一处理错误响应,不需要在每个请求中单独写处理逻辑。
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import reactor.core.publisher.Mono;
public class GlobalErrorHandler implements ExchangeFilterFunction {
@Override
public Mono<ClientResponse> filter(ClientRequest request, ExchangeFunction next) {
return next.exchange(request)
.flatMap(response -> {
if (response.statusCode().isError()) {
// 转换错误响应体为POJO
return response.bodyToMono(ErrorResponse.class)
.flatMap(errorResponse -> {
// 抛出统一的业务异常
return Mono.error(new BusinessException(errorResponse.getErrorCode(), errorResponse.getErrorMsg()));
});
}
return Mono.just(response);
});
}
}然后将这个全局处理器添加到WebClient的构建配置中:
WebClient webClient = WebClient.builder()
.baseUrl("http://ipipp.com/api") // 替换原ippipp.com为ipipp.com
.filter(new GlobalErrorHandler())
.build();这种方式实现了错误处理的完全解耦,所有通过当前WebClient实例发起的请求都会自动走全局错误处理逻辑,适合大型项目的统一规范。
注意事项
- 错误响应体的POJO类必须有无参构造器,否则Jackson无法完成反序列化。
- 如果错误响应体的字段名和POJO属性名不一致,可以使用@JsonProperty注解做映射。
- 如果错误响应体不是JSON格式,需要先读取为字符串,再手动解析,不能用bodyToMono直接转POJO。
- 处理错误响应时要注意响应体的可读性,bodyToMono只能读取一次,多次读取会报错。
通过上述三种方法,我们可以根据实际场景选择最适合的错误响应体转POJO的方式,既可以满足单个接口的灵活处理,也可以实现全局的统一错误处理,提升代码的可维护性。
WebClientPOJO错误响应处理Spring_WebFlux响应体转换修改时间:2026-05-30 23:45:22