0

0

Spring WebClient错误响应体转换为POJO对象教程

花韻仙語

花韻仙語

发布时间:2025-10-16 13:12:34

|

239人浏览过

|

来源于php中文网

原创

Spring WebClient错误响应体转换为POJO对象教程

本教程详细讲解如何将spring webclient在处理http错误时返回的字符串格式响应体转换为自定义java pojo对象。通过创建匹配错误结构体的pojo类,并利用webclient的错误处理机制结合json转换器,实现对错误信息的结构化解析,提升错误处理的便捷性和可读性。

在使用Spring WebClient进行HTTP请求时,处理正常响应体通常很简单,但当远程服务返回HTTP错误状态码(如4xx或5xx)时,WebClient默认会将错误响应体作为字符串处理,或者直接抛出WebClientResponseException。为了更有效地解析和利用这些错误信息,将其转换为结构化的Java POJO对象是最佳实践。这不仅提高了代码的可读性,也方便了后续的业务逻辑处理。

1. 理解WebClient的错误处理机制

WebClient提供了灵活的错误处理API,主要通过onStatus和onErrorResume等方法。

  • onStatus(Predicate statusPredicate, Function> exceptionFunction): 允许我们根据HTTP状态码定义自定义的错误处理逻辑。在exceptionFunction中,我们可以访问ClientResponse对象,从而读取错误响应体。
  • onErrorResume(Function> fallbackFunction): 当上游Mono/Flux序列中发生任何错误时,提供一个备用序列来恢复。这通常用于处理已经抛出的异常。

关键在于,当错误发生时,如何从ClientResponse中提取并转换响应体。

2. 定义错误响应POJO

首先,我们需要根据远程服务可能返回的错误响应JSON结构,定义一个对应的Java POJO(Plain Old Java Object)类。例如,如果错误响应体是:

{
    "timestamp": "2023-10-27T10:00:00.000+00:00",
    "status": 400,
    "error": "Bad Request",
    "message": "Invalid input parameters provided.",
    "path": "/api/resource"
}

那么,对应的Java POJO可以定义如下:

import java.time.LocalDateTime;

public class ErrorResponse {
    private LocalDateTime timestamp;
    private int status;
    private String error;
    private String message;
    private String path;

    // 必须包含无参构造函数
    public ErrorResponse() {}

    // 包含所有字段的构造函数(可选,但推荐)
    public ErrorResponse(LocalDateTime timestamp, int status, String error, String message, String path) {
        this.timestamp = timestamp;
        this.status = status;
        this.error = error;
        this.message = message;
        this.path = path;
    }

    // Getter和Setter方法
    public LocalDateTime getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(LocalDateTime timestamp) {
        this.timestamp = timestamp;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    @Override
    public String toString() {
        return "ErrorResponse{" +
               "timestamp=" + timestamp +
               ", status=" + status +
               ", error='" + error + '\'' +
               ", message='" + message + '\'' +
               ", path='" + path + '\'' +
               '}';
    }
}

注意事项:

Dreamhouse AI
Dreamhouse AI

AI室内设计,快速重新设计你的家,虚拟布置家具

下载
  • POJO的字段名必须与JSON键名精确匹配(包括大小写),否则JSON转换器可能无法正确映射。
  • 确保POJO包含一个无参构造函数,这是许多JSON库进行反序列化时的基本要求。
  • 如果JSON键名与Java字段名不一致,可以使用@JsonProperty("jsonKeyName")注解进行映射。

3. 实现错误响应转换

在WebClient调用中,我们可以结合onStatus方法和bodyToMono来将错误响应体转换为POJO。

import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;

public class WebClientErrorConverter {

    private final WebClient webClient;

    public WebClientErrorConverter(WebClient webClient) {
        this.webClient = webClient;
    }

    public Mono callRemoteService() {
        return webClient.get()
                .uri("/api/resource") // 假设这个URI会返回错误
                .retrieve()
                // 使用onStatus处理非2xx状态码
                .onStatus(HttpStatus::is4xxClientError, clientResponse ->
                    clientResponse.bodyToMono(ErrorResponse.class) // 将错误响应体转换为ErrorResponse POJO
                                  .flatMap(errorBody -> {
                                      // 这里可以根据errorBody的内容抛出自定义异常
                                      System.err.println("Client Error: " + errorBody.getMessage());
                                      return Mono.error(new CustomServiceException(
                                          "Client error from remote service: " + errorBody.getMessage(),
                                          errorBody.getStatus(),
                                          errorBody.getError()
                                      ));
                                  })
                )
                .onStatus(HttpStatus::is5xxServerError, clientResponse ->
                    clientResponse.bodyToMono(ErrorResponse.class) // 同样处理5xx错误
                                  .flatMap(errorBody -> {
                                      System.err.println("Server Error: " + errorBody.getMessage());
                                      return Mono.error(new CustomServiceException(
                                          "Server error from remote service: " + errorBody.getMessage(),
                                          errorBody.getStatus(),
                                          errorBody.getError()
                                      ));
                                  })
                )
                .bodyToMono(String.class) // 正常响应体预期为String
                .onErrorResume(CustomServiceException.class, ex -> {
                    // 在这里处理自定义异常,例如记录日志或返回默认值
                    System.err.println("Caught custom service exception: " + ex.getMessage());
                    return Mono.just("Fallback response due to service error.");
                })
                .onErrorResume(WebClientResponseException.class, ex -> {
                    // 处理未能转换为POJO的WebClientResponseException
                    System.err.println("Caught generic WebClientResponseException: " + ex.getStatusCode() + " - " + ex.getResponseBodyAsString());
                    return Mono.just("Fallback response due to generic WebClient error.");
                })
                .onErrorResume(Throwable.class, ex -> {
                    // 捕获其他所有异常
                    System.err.println("Caught unexpected exception: " + ex.getMessage());
                    return Mono.just("Fallback response due to unexpected error.");
                });
    }

    // 示例自定义异常类
    public static class CustomServiceException extends RuntimeException {
        private final int statusCode;
        private final String errorType;

        public CustomServiceException(String message, int statusCode, String errorType) {
            super(message);
            this.statusCode = statusCode;
            this.errorType = errorType;
        }

        public int getStatusCode() {
            return statusCode;
        }

        public String getErrorType() {
            return errorType;
        }
    }

    public static void main(String[] args) {
        // 示例WebClient配置
        WebClient webClient = WebClient.builder()
                .baseUrl("http://localhost:8080") // 替换为你的服务地址
                .build();

        WebClientErrorConverter converter = new WebClientErrorConverter(webClient);
        converter.callRemoteService().subscribe(
                success -> System.out.println("Success: " + success),
                error -> System.err.println("Error during subscription: " + error.getMessage())
        );
    }
}

在上述代码中:

  1. 我们使用onStatus(HttpStatus::is4xxClientError, ...)和onStatus(HttpStatus::is5xxServerError, ...)来分别处理客户端和服务器错误。
  2. 在onStatus的回调函数中,clientResponse.bodyToMono(ErrorResponse.class)是核心,它指示WebClient使用其配置的HTTP消息转换器(通常是Jackson或Gson)将响应体字符串反序列化为ErrorResponse对象。
  3. flatMap用于在获取到ErrorResponse对象后,将其封装成一个自定义的异常(如CustomServiceException),然后通过Mono.error()传播这个异常。
  4. 最终的onErrorResume链用于捕获并处理这些自定义异常,或者未能成功转换的原始WebClientResponseException。

4. JSON转换器:幕后英雄

Spring Boot默认集成了Jackson作为JSON处理器。当你将Jackson或Gson库添加到项目中时,Spring Boot会自动配置相应的HttpMessageReader,使得bodyToMono(YourPojo.class)能够自动进行JSON到POJO的转换。无需手动调用ObjectMapper或Gson实例,WebClient会为你处理这些细节。

5. 总结

通过以上步骤,我们能够将Spring WebClient在遇到HTTP错误时返回的字符串响应体,有效地转换为结构化的Java POJO对象。这种方法极大地提升了错误处理的灵活性和代码的可维护性,使得开发者可以基于具体的错误信息进行更精细的业务逻辑判断和用户反馈。关键在于正确定义与错误JSON结构匹配的POJO类,并利用WebClient的onStatus结合bodyToMono方法进行转换。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

842

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

742

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

739

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

399

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

431

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16926

2023.08.03

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

38

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.9万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.0万人学习

React核心原理新老生命周期精讲
React核心原理新老生命周期精讲

共12课时 | 1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号