当前位置: 首页 > news >正文

Springboot优雅实现对接口返回统一封装

前端在调用后端接口时往往不同的接口返回的数据是不一样的,但是通常我们会与前端约定一个固定的返回格式,通过固定的格式告诉他们什么时候接口是返回成功,什么时候返回失败,返回成功后他们如何拿到接口返回的数据去渲染前端页面。
在不对接口统一包装时,你可能会这样的返回如一个查询接口

    @PostMapping(value = "/list")public List<Map<String, Object>> list() {List<Map<String, Object>> mapList = new ArrayList<>();HashMap<String, Object> map = new HashMap<>();map.put("dazhi", "大智");map.put("zhangsan", "张三");map.put("laoliu", "老六");mapList.add(map);return mapList;}

接口返回

又或者这样的如一个删除接口

    @PostMapping(value = "/delete")public String delete() {return "删除完毕";}

接口返回

像这些情况如果你和前端开发人员联调接口她们就会很懵逼,由于我们没有给他一个统一的格式,前端人员不知道如何处理返回值。所以我们需要定义一个统一的标准返回格式的。
一个标准的返回格式至少包含3部分:
code 状态码:统一定义各种返回结果的状态码。
msg 描述:接口调用的结果描述。
data 数据:返回的数据。

{"code": "S000","msg": "操作成功!","data": "数据更新成功!"
}

我们使用@RestControllerAdvice注解并且实现ResponseBodyAdvice接口来实现统一返回格式的封装,关于使用@RestControllerAdvice实现全局异常处理可以看我以前的文章《Springboot全局异常处理从配置文件中读取自定义异常信息》,接下来展示一下大概的代码

定义一个标准的统一返回实体

package com.yx.limit.base.vo;import com.yx.limit.base.enums.ResponseEnum;
import lombok.Data;/*** @Author yx* @Description 统一响应实体*/
@Data
public class ResponseVo<T> {/*** 响应编码*/private String code;/*** 消息内容*/private String msg;/*** 响应数据*/private T data;private ResponseVo() {}private enum Singleton{INSTANCE;private ResponseVo responseVo;Singleton(){if (responseVo == null){responseVo = new ResponseVo();}}public ResponseVo getInstance(){return responseVo;}}public static <T> ResponseVo<T> success() {return success(null);}public static <T> ResponseVo<T> success(T data) {ResponseVo<T> responseVo = Singleton.INSTANCE.getInstance();responseVo.setCode(ResponseEnum.SUCCESS.getResultCode());responseVo.setMsg(ResponseEnum.SUCCESS.getResultMsg());responseVo.setData(data);return responseVo;}public static <T> ResponseVo<T> error(String code, String msg) {ResponseVo<T> responseVo = Singleton.INSTANCE.getInstance();responseVo.setCode(code);responseVo.setMsg(msg);responseVo.setData(null);return responseVo;}public static <T> ResponseVo<T> error(String msg) {ResponseVo<T> responseVo = Singleton.INSTANCE.getInstance();responseVo.setCode(ResponseEnum.ERROR.getResultCode());responseVo.setMsg(ResponseEnum.ERROR.getResultMsg());responseVo.setData(null);return responseVo;}
}


定义一个状态码枚举

package com.yx.limit.base.enums;import lombok.AllArgsConstructor;
import lombok.Getter;/*** @Author yx* @Description 响应编码枚举*/
@AllArgsConstructor
public enum ResponseEnum {/*** 数据操作错误定义*/SUCCESS("S000","操作成功!"),ERROR("E000","操作失败!"),SIGNATURE_NOT_MATCH("E001","请求的数字签名不匹配!"),BODY_NOT_MATCH("E002","请求的数据格式不符!"),INTERNAL_SERVER_ERROR("E003", "服务器内部错误!");/*** 错误码*/@Getterprivate String resultCode;/*** 错误描述*/@Getterprivate String resultMsg;
}


定义一个忽略自动包装返回功能的注解

package com.yx.limit.base.annotations;import java.lang.annotation.*;/*** @Author yx* @Description 忽略自动返回构造注解*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreAutoResponse {
}


统一响应结果通知类 

package com.yx.light.element.mybatis.advice;import com.fasterxml.jackson.databind.ObjectMapper;
import com.yx.limit.base.annotations.IgnoreAutoResponse;
import com.yx.limit.base.vo.ResponseVo;
import lombok.SneakyThrows;
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.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;/*** @Author yx* @Description 统一响应结果通知*/
@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice<Object> {private final ObjectMapper objectMapper;public ResponseAdvice(ObjectMapper objectMapper) {this.objectMapper = objectMapper;}@Overridepublic boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {return !methodParameter.hasMethodAnnotation(IgnoreAutoResponse.class);}@SneakyThrows@Overridepublic Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {//SpringBoot的Controller中的方法返回值是String时会直接返回if (o instanceof String) {return objectMapper.writeValueAsString(ResponseVo.success(o));}//全局异常处理的结果直接返回即可if (o instanceof ResponseVo) {return o;}return ResponseVo.success(o);}
}

 这个时候我们再来请求原来的两个方法查看返回结果
list方法:

delete方法:

我们发现delete的方法返回的json格式没有格式化,我们只需要稍加改造一下delete方法就能正常返回格式化的数据

    @PostMapping(value = "/delete", produces = "application/json; charset=UTF-8")public String delete() {return "删除完毕";}

 

对于一些不想返回固定包装的方法可以在方法上加上@IgnoreAutoResponse注解即可返回原始的格式

    @PostMapping(value = "/original")@IgnoreAutoResponsepublic String original() {return "原始字符串";}

 

相关文章:

Springboot优雅实现对接口返回统一封装

前端在调用后端接口时往往不同的接口返回的数据是不一样的&#xff0c;但是通常我们会与前端约定一个固定的返回格式&#xff0c;通过固定的格式告诉他们什么时候接口是返回成功&#xff0c;什么时候返回失败&#xff0c;返回成功后他们如何拿到接口返回的数据去渲染前端页面。…...

Kafka 安装与部署

目录 Kafka 下载 &#xff08;1&#xff09;将 kafka_2.11-2.4.1.tgz 上传至 /opt/software/ &#xff08;2&#xff09;解压安装包至 /opt/module/ [huweihadoop101 ~]$ cd /opt/software/ [huweihadoop101 software]$ tar -zxvf kafka_2.11-2.4.1.tgz -C ../module/&#…...

计算 N*4*4 位姿形状的逆变换,在N*3*4位姿后补充 [0,0,0,1]

针对 [N,4,4] shape 的 poses&#xff0c;函数 ComputeInversePoses 返回 相同 shape&#xff0c;但是每个 pose 都是前面的 逆 pose。 针对 [N,3,4] shape 的 poses&#xff0c;函数 AddIdentityToPoses 返回 在每个 [3,4] pose下加上 [0,0,0,1] 后的pose&#xff0c;返回的…...

人工智能可以战胜人类智慧大脑么?

引言 在当今快速发展的科技时代&#xff0c;人工智能的进步日新月异&#xff0c;引发了一场深刻的讨论&#xff1a;能否有一天&#xff0c;人工智能能够超越甚至战胜人类智慧&#xff1f;这个问题涉及到人类认知的广泛领域&#xff0c;牵涉到人类思维的深层次特质以及AI技术在…...

【数据结构和算法】 K 和数对的最大数目

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;双指针排序 三、代码 3.1 方法一&#xff1a;双指针排序 3.2 方法二&#xff1…...

基于ssm高校推免报名系统源码和论文

网络的广泛应用给生活带来了十分的便利。所以把高校推免报名管理与现在网络相结合&#xff0c;利用java技术建设高校推免报名管理系统&#xff0c;实现高校推免报名的信息化。则对于进一步提高高校推免报名管理发展&#xff0c;丰富高校推免报名管理经验能起到不少的促进作用。…...

算法设计与分析2023秋-头歌实验-实验七 动态规划

文章目录 第1关&#xff1a;数塔问题任务描述相关知识编程要求解题思路测试说明参考答案 第2关&#xff1a;最长公共子序列任务描述相关知识编程要求解题思路&#xff1a;测试说明参考答案 第3关&#xff1a;求序列-2 11 -4 13 -5 -2的最大子段和任务描述相关知识编程要求解题思…...

复杂 SQL 实现分组分情况分页查询

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、根据 camp_status 字段分为 6 种情况 1.1 SQL语句 1.2 SQL解释 二、分页 SQL 实现 2.1 SQL语句 2.2 根据 camp_type 区分返…...

JavaScript---如何完美的判断返回对象是否有值

如何判断一个对象为空是我们在开发中经常会遇到的问题&#xff0c;今天我们来聊聊几种经常使用的方法&#xff0c;以及在不同的场景下我们如何去使用。 1. JSON.stringify JSON.stringify 方法可以使对象序列化&#xff0c;转为相应的 JSON 格式。 js 复制代码 const obj {…...

kafka offset sasl加密连接

kafka-tool&#xff08;offset&#xff09; 进行SCRAM连接&#xff0c;直接上图 填写jaas的认证&#xff08;账密 引用包&#xff09;...

Android studio矩形背景颜色以及弧度的设置

在这里插入图片描述 Android的shape中主要设置的属性 corners&#xff1a;用于设置形状的圆角&#xff0c;可以设置圆角的半径、颜色等属性。 stroke&#xff1a;用于设置形状的边框&#xff0c;可以设置边框的宽度、颜色等属性。 padding&#xff1a;用于设置形状的内边距&…...

Acrel-1000DP分布式光伏系统在某重工企业18MW分布式光伏中应用——安科瑞 顾烊宇

摘 要&#xff1a;分布式光伏发电特指在用户场地附近建设&#xff0c;运行方式以用户侧自发自用、余电上网&#xff0c;且在配电系统平衡调节为特征的光伏发电设施&#xff0c;是一种新型的、具有广阔发展前景的发电和能源综合利用方式&#xff0c;它倡导就近发电&#xff0c;就…...

3 python基本语法 - Dict 字典

Python 中字典&#xff08;dict&#xff09;是一种无序的、可变的序列&#xff0c;它的元素以“键值对&#xff08;key-value&#xff09;”的形式存储。相对地&#xff0c;列表&#xff08;list&#xff09;和元组&#xff08;tuple&#xff09;都是有序的序列&#xff0c;它们…...

Magnific AI:彻底改变 AI 生成图像的升级

在我最近与 Magnific AI 的讨论中&#xff0c;我不仅感到惊讶&#xff0c;而且对该工具提供的质量和可能性着迷。我发现 Magnific AI 能够转换人工智能生成的图像&#xff08;这些图像通常只能以低分辨率提供&#xff09;&#xff0c;尤其令人印象深刻&#xff0c;不仅在可打印…...

BKP 备份寄存器 RTC 实时时钟-stm32入门

这一章节我们要讲的主要内容是 RTC 实时时钟&#xff0c;对应手册&#xff0c;是第 16 章的位置。 实时时钟这个东西&#xff0c;本质上是一个定时器&#xff0c;但是这个定时器&#xff0c;是专门用来产生年月日时分秒&#xff0c;这种日期和时间信息的。所以学会了 STM32 的…...

1.1 数据结构-数据的表示

文章目录 1.1.1 二元关系及其性质:1.1.1.1 笛卡尔积:1.1.1.2 二元关系:持续更新当中 ....... 1.1.1 二元关系及其性质: 数据的基本单元称为额数据元素,数据是从客观事物的观测中的到的,数据元素并不是鼓励存在的,而是存在密切的联系,也因此才能表示和描述客观事物,数据元素之间…...

UNIX Linux系统 启动PPOCRLabel报错[已放弃 (核心已转储)]

参照官方教程安装后&#xff0c;启动PPOCRLabel报错&#xff1a;[已放弃 (核心已转储)] 官方链接地址&#xff1a;PPOCRLabelv2 $~ PPOCRLabel --lang ch QObject::moveToThread: Current thread (0x561534309430) is not the objects thread (0x56153929eac0). Cannot move to…...

前端开发中的webpack打包工具

前端技术发展迅猛&#xff0c;各种可以提高开发效率的新思想和框架层出不穷&#xff0c;但是它们都有一个共同点&#xff0c;即源代码无法直接运行&#xff0c;必须通过转换后才可以正常运行。webpack是目前主流的打包模块化JavaScript的工具之一。 本章主要涉及的知识点有&am…...

Mybatis配置-数据库厂商标识(databaseIdProvider)

MyBatis可以根据数据库供应商执行不同的语句。多数据库供应商支持是基于映射语句的databaseId属性。MyBatis将加载所有没有databaseId属性或具有与当前数据库匹配的databaseId属性的语句。如果找到具有和不具有databaseId的相同语句&#xff0c;则后者将被丢弃。要启用多供应商…...

【Java】使用递归的方法获取层级关系数据demo

使用递归来完善各种业务数据的层级关系的获取 引言&#xff1a;在Java开发中&#xff0c;我们通常会遇到层层递进的关系型数据的获取问题&#xff0c;有时是树状解构&#xff0c;或金字塔结构&#xff0c;怎么描述都行&#xff0c;错综复杂的关系在程序中还是可以理清的。 这…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...