SpringBoot统一数据返回的几种方式

 更新时间:2024年07月19日 09:35:55   作者:码农阿豪@新空间代码工作室  
在Web应用程序开发中,统一数据返回格式对于前后端分离项目尤为重要,本文就来介绍一下SpringBoot统一数据返回的几种方式,具有一定的参考价值,感兴趣的可以了解一下

在Web应用程序开发中,统一数据返回格式对于前后端分离项目尤为重要。通过统一的数据返回格式,可以大大简化前端数据解析的复杂度,提高代码的可维护性和一致性。本文将介绍如何在Spring Boot项目中实现统一的数据返回格式。

一、概念

统一数据返回指的是将所有接口的返回数据进行统一封装,使用一致的格式返回给前端。例如,可以定义一个标准的响应格式,包括状态码、消息、数据等信息:

{
    "code": 200,
    "message": "Success",
    "data": { ... }
}

通过这种方式,前端开发人员只需处理一种响应格式,减少解析错误和代码冗余。

二、实现统一数据返回

为了实现统一的数据返回格式,我们可以使用Spring Boot的ResponseBodyAdvice接口,该接口可以在响应返回之前对响应体进行处理。

2.1 重写responseAdvice方法

首先,我们需要创建一个类,实现ResponseBodyAdvice接口,并重写其中的方法:

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;

@ControllerAdvice
public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> {

    @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 ResponseEntity) {
            return body;
        }
        return new ApiResponse(200, "Success", body);
    }
}

在上面的代码中,supports方法用于判断哪些接口的返回值需要处理,这里返回true表示处理所有接口的返回值。beforeBodyWrite方法则是在响应体写入之前进行处理,将返回的数据封装为统一格式的ApiResponse对象。

2.2 实现ApiResponse类

创建ApiResponse类,用于定义统一的响应格式:

public class ApiResponse<T> {

    private int code;
    private String message;
    private T data;

    public ApiResponse(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    // Getters and Setters
}

三、特殊类型-String的处理

由于Spring在处理String类型的返回值时,会直接将其写入响应体,而不会经过HttpMessageConverter,因此我们需要对String类型进行特殊处理:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@ControllerAdvice
public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> {

    private final ObjectMapper objectMapper;

    public GlobalResponseAdvice(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, 
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, 
                                  ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof String) {
            try {
                return objectMapper.writeValueAsString(new ApiResponse<>(200, "Success", body));
            } catch (Exception e) {
                throw new RuntimeException("Failed to write response as String", e);
            }
        }
        if (body instanceof ResponseEntity) {
            return body;
        }
        return new ApiResponse<>(200, "Success", body);
    }
}

在上面的代码中,我们使用ObjectMapperApiResponse对象转换为String,确保String类型的返回值也能统一为标准格式。

四、全部代码

// ApiResponse.java
public class ApiResponse<T> {

    private int code;
    private String message;
    private T data;

    public ApiResponse(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    // Getters and Setters
}

// GlobalResponseAdvice.java
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
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;

@ControllerAdvice
public class GlobalResponseAdvice implements ResponseBodyAdvice<Object> {

    private final ObjectMapper objectMapper;

    public GlobalResponseAdvice(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, 
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, 
                                  ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof String) {
            try {
                return objectMapper.writeValueAsString(new ApiResponse<>(200, "Success", body));
            } catch (Exception e) {
                throw new RuntimeException("Failed to write response as String", e);
            }
        }
        if (body instanceof ResponseEntity) {
            return body;
        }
        return new ApiResponse<>(200, "Success", body);
    }
}

通过上述代码,我们可以实现Spring Boot项目中统一的数据返回格式。无论返回的数据类型如何,都可以通过统一封装后的格式返回给前端,极大地提高了代码的可维护性和前后端的开发效率。

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

相关文章

  • MyBatis-Plus批量操作SQL日志不打印问题的解决方案

    MyBatis-Plus批量操作SQL日志不打印问题的解决方案

    在使用 MyBatis-Plus 的 saveBatch() 和 updateBatchById() 方法进行批量数据操作时,发现自定义的 Druid SQL 日志拦截器无法打印这些批量操作的 SQL 语句,导致调试和问题排查困难,本文给大家该问题的详细解决方案,需要的朋友可以参考下
    2026-03-03
  • Java线程的创建介绍及实现方式示例

    Java线程的创建介绍及实现方式示例

    这篇文章主要为大家介绍了Java线程的创建介绍及实现方式示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Lucene 索引删除策略源码解析

    Lucene 索引删除策略源码解析

    这篇文章主要为大家介绍了Lucene 索引删除策略源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • JAVA日常开发中读写XML的方法详解

    JAVA日常开发中读写XML的方法详解

    这篇文章主要介绍了JAVA日常开发中读写XML的相关资料,详细讲解了在Java中如何使用DOM(文档对象模型)和SAX(简单API for XML)两种方式读取XML文件,以及如何使用DOM和JAXB(Java Architecture for XML Binding)两种方式写入XML文件,需要的朋友可以参考下
    2024-12-12
  • 三种Spring AI本地/低成本模型接入方案

    三种Spring AI本地/低成本模型接入方案

    文章详细介绍了三种本地低成本接入模型方案的配置与实战代码,包括Ollama本地大模型零成本运行、DashScope国内低价直连通义千问和API代理统一管理多模型,每种方案都有详细步骤、配置代码和适用场景,帮助开发者根据实际需求选择合适的接入方案,需要的朋友可以参考下
    2026-04-04
  • Spring整合Mybatis方式之注册映射器

    Spring整合Mybatis方式之注册映射器

    这篇文章主要介绍了Spring整合Mybatis方式之注册映射器,MapperFactoryBean注册映射器的最大问题,就是需要一个个注册所有的映射器,而实际上mybatis-spring提供了扫描包下所有映射器接口的方法,每种方式给大家介绍的非常详细,需要的朋友参考下吧
    2024-03-03
  • Springboot如何正确使用AOP问题

    Springboot如何正确使用AOP问题

    这篇文章主要介绍了Springboot如何正确使用AOP问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • SpringMVC请求数据详解讲解

    SpringMVC请求数据详解讲解

    Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet,Spring MVC 角色划分清晰,分工明细,本章来讲解SpringMVC如何请求数据
    2022-07-07
  • Java详细讲解IO流的Writer与Reader操作

    Java详细讲解IO流的Writer与Reader操作

    Writer与Reader类不能直接调用,需要使用多带的方法调用它们的子类,在他们的前边加上一个File即可如(FileWriter或FileReader)的多态方法进行其调用,并且他们也是抽象类调用需要连接接口Exception,它们的优点在于可以直接写入或读出内容,不需要使用byte转八进制
    2022-05-05
  • String与XML互转以及从XML取节点值并修改的方法

    String与XML互转以及从XML取节点值并修改的方法

    今天小编就为大家分享一篇String与XML互转以及从XML取节点值并修改的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07

最新评论