SpringBoot之统一数据返回格式的实现示例

 更新时间:2025年12月18日 08:30:29   作者:新绿MEHO  
本文主要介绍了SpringBoot之统一数据返回格式的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

之前我们实现的图书管理系统,函数的返回值格式都不统一,如果将这些函数的返回值格式都进行统一,将方便后续的返回和接收,但是如果我们挨个修改这些函数的返回值格式,有些麻烦,那么有没有别的好的办法呢?----有,就是下面我们要讲解的"SpringBoot之统一数据返回格式"。

统一数据返回格式

使用

统⼀的数据返回格式使⽤ @ControllerAdvice 和 ResponseBodyAdvice 的⽅式实现
@ControllerAdvice 表⽰控制器通知类。

定义类 ResponseAdvice , 实现 ResponseBodyAdvice 接⼝, 并在类上添加
@ControllerAdvice 注解。

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof Result){
            return body;
        }

        return Result.success(body);
    }
}

运行结果:

定义测试接口

@RequestMapping("/test")
@RestController
public class TestController {
    @RequestMapping("/t1")
    public String t1(){
        return "string";
    }

    @RequestMapping("/t2")
    public Integer t2(){
        return 1;
    }

    @RequestMapping("/t3")
    public Boolean t3(){
        return true;
    }

}

运行结果

t2返回结果:

t3返回结果:

t1返回结果:

为什么其他方法都能够正常返回,而返回类型为String时却不能正常返回,而且还抛出了ClassCastException异常,这是为什么呢?

问题解答(结合源码)

根据IDEA控制台打印的堆栈信息,我们首先看看StringHttpMessageConverter和AbstractHttpMessageConverter这两个类,特别是StringHttpMessageConverter的addDefaultHeaders方法和AbstractHttpMessageConverter的write方法,其中StringHttpMessageConverter是继承了AbstractHttpMessageConverter并重写了几个方法,特别是addDefaultHeaders方法,下面通过Debug方式运行:

再继续运行,会捕获到异常

由此我们知道,是因为返回结果为String类型的"string"被转换成了Result类型,但是在执行AbstractHttpMessageConverter的write方法时,因为AbstractHttpMessageConverter的派生类StringHttpMessageConverter重写了addDefaultHeaders方法,此时会调用StringHttpMessageConverter的addDefaultHeaders方法,但是StringHttpMessageConverter的addDefaultHeaders方法要求 t 的类型是String类型,但是无法从自定义的Result类型转换成String类型,因此抛出了ClassCastException异常。

那么问题来了,上面的三个测试接口,走的都是Result.success()方法,为什么却有不一样的结果,通过调试:

对于返回类型为String类型,在AbstractMessageConverterMethodProcessor里面的writeWithMessageConverters()方法时,在经过下图所示过程中,String类型会被转换成Result类型的结果,而且后面走的是StringHttpMessageConverter的addDefaultHeaders方法,其中StringHttpMessageConverter重写了AbstractHttpMessageConverter的addDefaultHeaders方法;

而返回值类型不是String类型时,经过和刚刚同样的步骤时,直接走的是AbstractHttpMessageConverter的addDefaultHeaders方法,而没有走StringHttpMessageConverter的addDefaultHeaders方法。

解决方法:对返回类型为String类型的字符串进行序列化

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import springbook.model.Result;

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof Result){
            return body;
        }
        if (body instanceof String){
            return objectMapper.writeValueAsString(Result.success(body));
        }
        return Result.success(body);
    }
}

运行结果:

优点

1. ⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据
2. 降低前端程序员和后端程序员的沟通成本, 按照某个格式实现就可以了, 因为所有接⼝都是这样返回的.
3. 有利于项⽬统⼀数据的维护和修改.
4. 有利于后端技术部⻔的统⼀规范的标准制定, 不会出现稀奇古怪的返回内容.

到此这篇关于SpringBoot之统一数据返回格式的实现示例的文章就介绍到这了,更多相关SpringBoot 统一数据返回格式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java负载均衡策略的实现详解

    Java负载均衡策略的实现详解

    这篇文章主要介绍了Java负载均衡策略的实现,负载均衡在Java领域中有着广泛深入的应用,不管是大名鼎鼎的nginx,还是微服务治理组件如dubbo,feign等,负载均衡的算法在其中都有着实际的使用,需要的朋友可以参考下
    2022-07-07
  • Java实现图书管理系统的示例代码

    Java实现图书管理系统的示例代码

    这篇文章将通过Java实现一个简答的图书管理系统,本图书管理系统用对象数组的方式来提供操作方法,比较特别,建议新手学习,这对理解Java面向对象有很大帮助
    2022-11-11
  • Java线程创建静态代理模式代码实例

    Java线程创建静态代理模式代码实例

    这篇文章主要介绍了Java线程创建静态代理模式代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • java 请求跨域问题解决方法实例详解

    java 请求跨域问题解决方法实例详解

    这篇文章主要介绍了java 请求跨域问题解决方法实例详解的相关资料,需要的朋友可以参考下
    2017-04-04
  • Mybatis 中如何判断集合的size

    Mybatis 中如何判断集合的size

    这篇文章主要介绍了在Mybatis中判断集合的size操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • idea文件夹平铺问题及解决

    idea文件夹平铺问题及解决

    用户发现IntelliJ IDEA文件夹平铺显示异常,通过右侧齿轮按钮调整设置,将HideEmptyMiddlePackages改为CompactMiddlePackages后,问题解决,界面恢复正常
    2025-07-07
  • 一文详解Spring Aop @After(后置通知)的使用场景

    一文详解Spring Aop @After(后置通知)的使用场景

    @After 是 Spring AOP 中的另一种通知(Advice)类型,通常被称为“后置通知”或“最终通知”,本文将通过详细的代码示例给大家介绍一下Spring Aop @After(后置通知)的使用场景,需要的朋友可以参考下
    2025-06-06
  • Spring boot 使用JdbcTemplate访问数据库

    Spring boot 使用JdbcTemplate访问数据库

    SpringBoot 是为了简化 Spring 应用的创建、运行、调试、部署等一系列问题而诞生的产物。本文重点给大家介绍spring boot 使用JdbcTemplate访问数据库,需要的朋友可以参考下
    2018-05-05
  • 四步教你完美解决IDEA运行maven项目时报错:java: 错误: 不支持发行版本 5

    四步教你完美解决IDEA运行maven项目时报错:java: 错误: 不支持发行版本 5

    这篇文章主要介绍了四步教你完美解决IDEA运行maven项目时报错:java: 错误: 不支持发行版本 5的相关资料,文中通过图文将解决的办法介绍的非常详细,需要的朋友可以参考下
    2025-09-09
  • Java Stream 的 forEachOrdered 与 forEach的区别与适用场景

    Java Stream 的 forEachOrdered 与 forE

    在Java Stream API中,forEach和forEachOrdered是两个常用的终止操作,用于对流中的元素执行迭代处理,本文将从多个维度深入分析Java Stream的forEachOrdered与forEach的区别与适用场景,感兴趣的朋友一起看看吧
    2025-08-08

最新评论