导读:本期聚焦于小伙伴创作的《如何将Spring WebClient错误响应体转换为Java POJO》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何将Spring WebClient错误响应体转换为Java POJO》有用,将其分享出去将是对创作者最好的鼓励。

在使用Spring WebClient发起HTTP请求时,我们通常会很顺利地将2xx成功响应体转换为自定义的Java POJO,但遇到4xx、5xx这类错误响应时,默认的处理逻辑往往不会自动把错误响应体映射到我们定义的错误POJO上,导致无法便捷地获取错误信息。下面我们就一步步解决这个问题。

如何将Spring WebClient错误响应体转换为Java POJO

常见错误响应场景说明

假设我们调用的外部接口在出错时会返回如下格式的JSON响应:

{
    "code": 400,
    "message": "参数校验失败",
    "detail": "用户ID不能为空"
}

我们通常会定义对应的错误POJO类:

public class ErrorResponse {
    private Integer code;
    private String message;
    private String detail;

    //  getter和setter方法
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getDetail() {
        return detail;
    }
    public void setDetail(String detail) {
        this.detail = detail;
    }

    @Override
    public String toString() {
        return "ErrorResponse{code=" + code + ", message='" + message + "', detail='" + detail + "'}";
    }
}

默认WebClient的问题

如果我们直接使用默认的WebClient发送请求,遇到错误响应时会抛出WebClientResponseException,此时错误响应体的内容只会以字符串形式存在,不会自动转换为ErrorResponse对象,示例代码如下:

WebClient webClient = WebClient.create("http://ipipp.com");
try {
    String result = webClient.get()
            .uri("/test")
            .retrieve()
            .bodyToMono(String.class)
            .block();
    System.out.println(result);
} catch (WebClientResponseException e) {
    // 此时e.getResponseBodyAsString()是JSON字符串,需要手动解析
    System.out.println("错误响应体:" + e.getResponseBodyAsString());
}

这种方式需要手动解析JSON字符串,不仅繁琐,还不符合我们统一使用POJO处理响应的习惯。

使用onStatus方法处理错误响应

WebClient的retrieve()方法提供了onStatus方法,我们可以指定特定状态码范围,自定义错误处理逻辑,将错误响应体转换为POJO:

WebClient webClient = WebClient.create("http://ipipp.com");
try {
    String result = webClient.get()
            .uri("/test")
            .retrieve()
            // 处理4xx和5xx的错误响应
            .onStatus(HttpStatus::is4xxClientError, clientResponse -> 
                clientResponse.bodyToMono(ErrorResponse.class)
                        .flatMap(errorResponse -> Mono.error(new BusinessException(errorResponse)))
            )
            .onStatus(HttpStatus::is5xxServerError, clientResponse -> 
                clientResponse.bodyToMono(ErrorResponse.class)
                        .flatMap(errorResponse -> Mono.error(new BusinessException(errorResponse)))
            )
            .bodyToMono(String.class)
            .block();
    System.out.println("请求结果:" + result);
} catch (BusinessException e) {
    System.out.println("业务异常:" + e.getErrorResponse());
}

这里我们定义了自定义的业务异常BusinessException,构造函数接收ErrorResponse对象:

public class BusinessException extends RuntimeException {
    private final ErrorResponse errorResponse;

    public BusinessException(ErrorResponse errorResponse) {
        super(errorResponse.getMessage());
        this.errorResponse = errorResponse;
    }

    public ErrorResponse getErrorResponse() {
        return errorResponse;
    }
}

使用ExchangeFilterFunction全局处理

如果项目中很多地方都需要处理错误响应转换,我们可以使用ExchangeFilterFunction实现全局的过滤处理,避免重复代码:

ExchangeFilterFunction errorHandlingFilter = ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
    if (clientResponse.statusCode().is4xxClientError() || clientResponse.statusCode().is5xxServerError()) {
        return clientResponse.bodyToMono(ErrorResponse.class)
                .flatMap(errorResponse -> Mono.error(new BusinessException(errorResponse)))
                .then(Mono.empty());
    }
    return Mono.just(clientResponse);
});

WebClient webClient = WebClient.builder()
        .filter(errorHandlingFilter)
        .baseUrl("http://ipipp.com")
        .build();

try {
    String result = webClient.get()
            .uri("/test")
            .retrieve()
            .bodyToMono(String.class)
            .block();
    System.out.println("请求结果:" + result);
} catch (BusinessException e) {
    System.out.println("业务异常:" + e.getErrorResponse());
}

注意事项

  • 确保错误POJO的字段和响应JSON的字段名称一致,或者使用@JsonProperty注解指定映射关系。
  • 如果错误响应体的格式不固定,可以先转换为Map类型,再根据实际内容提取信息。
  • 使用block()方法时需要注意线程上下文,避免在响应式链中随意使用阻塞方法。

通过以上两种方式,我们就可以很方便地将Spring WebClient的错误响应体转换为Java POJO,统一错误处理逻辑,让代码更简洁易维护。

Spring_WebClient错误响应体转换Java_POJOWebClient异常处理响应体解析修改时间:2026-05-30 23:37:00

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。