Spring Boot3统一结果封装

⛰️个人主页:     蒾酒

🔥系列专栏:《spring boot实战》

🌊山高路远,行路漫漫,终有归途。


目录

前置条件

封装目的 

常用格式

定义返回结果枚举类

定义返回结果封装类

对返回结果封装

测试封装


前置条件

已经初始化好一个spring boot项目且版本为3X,项目可正常启动。

作者版本为3.2.2

初始化教程:

新版idea(2023)创建spring boot3项目-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_62262918/article/details/135785412?spm=1001.2014.3001.5501

封装目的 

Spring Boot进行统一结果封装的主要目的是提高开发效率、降低代码重复率,并且提供一致的API响应格式,从而简化前后端交互和错误处理

具体好处如下:

  1. 方便前端处理:前端可以统一根据返回格式进行处理,而不用关注具体的返回类型和内容。

  2. 提高 API 的可读性和可维护性:统一结果封装可以使 API 的返回更加规范化,统一了 API 返回结果的格式,使得代码更加易于阅读和维护。

  3. 增加系统的健壮性:通过统一结果封装,能够更好地处理错误和异常情况,从而增加系统的健壮性和稳定性。

  4. 统一日志输出:通过统一结果封装,可以方便地记录请求参数、请求结果、异常信息等,方便后续的日志分析和排查问题。

常用格式

最常用的格式为状态码、提示信息、携带数据如图

具体格式还要看团队,这里我就使用这种通用的格式。

定义返回结果枚举类

通过使用这样的枚举类有助于避免硬编码的状态码和消息,提高了代码的可维护性。

import lombok.Getter;/*** @author mijiupro*/
@Getter
public enum ResultEnum {/* 成功状态码 */SUCCESS(1, "操作成功!"),/* 错误状态码 */FAIL(0, "操作失败!"),/* 参数错误:10001-19999 */PARAM_IS_INVALID(10001, "参数无效"),PARAM_IS_BLANK(10002, "参数为空"),PARAM_TYPE_BIND_ERROR(10003, "参数格式错误"),PARAM_NOT_COMPLETE(10004, "参数缺失"),/* 用户错误:20001-29999*/USER_NOT_LOGGED_IN(20001, "用户未登录,请先登录"),USER_LOGIN_ERROR(20002, "账号不存在或密码错误"),USER_ACCOUNT_FORBIDDEN(20003, "账号已被禁用"),USER_NOT_EXIST(20004, "用户不存在"),USER_HAS_EXISTED(20005, "用户已存在"),/* 系统错误:40001-49999 */FILE_MAX_SIZE_OVERFLOW(40003, "上传尺寸过大"),FILE_ACCEPT_NOT_SUPPORT(40004, "上传文件格式不支持"),/* 数据错误:50001-599999 */RESULT_DATA_NONE(50001, "数据未找到"),DATA_IS_WRONG(50002, "数据有误"),DATA_ALREADY_EXISTED(50003, "数据已存在"),AUTH_CODE_ERROR(50004, "验证码错误"),/* 权限错误:70001-79999 */PERMISSION_UNAUTHENTICATED(70001, "此操作需要登陆系统!"),PERMISSION_UNAUTHORIZED(70002, "权限不足,无权操作!"),PERMISSION_EXPIRE(70003, "登录状态过期!"),PERMISSION_TOKEN_EXPIRED(70004, "token已过期"),PERMISSION_LIMIT(70005, "访问次数受限制"),PERMISSION_TOKEN_INVALID(70006, "无效token"),PERMISSION_SIGNATURE_ERROR(70007, "签名失败");// 状态码int code;// 提示信息String message;ResultEnum(int code, String message) {this.code = code;this.message = message;}public int code() {return code;}public String message() {return message;}public void setCode(int code) {this.code = code;}public void setMessage(String message) {this.message = message;}
}

定义返回结果封装类

import com.mijiu.commom.enumerate.ResultEnum;
import lombok.Data;/*** @author mijiupro*/@Data
public class Result<T> {// 操作代码Integer code;// 提示信息String message;// 结果数据T data;public Result(ResultEnum resultCode) {this.code = resultCode.code();this.message = resultCode.message();}public Result(ResultEnum resultCode, T data) {this.code = resultCode.code();this.message = resultCode.message();this.data = data;}public Result(String message) {this.message = message;}//成功返回封装-无数据public static Result<String> success() {return new Result<String>(ResultEnum.SUCCESS);}//成功返回封装-带数据public static <T> Result<T> success(T data) {return new Result<T>(ResultEnum.SUCCESS, data);}//失败返回封装-使用默认提示信息public static Result<String> error() {return new Result<String>(ResultEnum.FAIL);}//失败返回封装-使用返回结果枚举提示信息public static Result<String> error(ResultEnum resultCode) {return new Result<String>(resultCode);}//失败返回封装-使用自定义提示信息public static Result<String> error(String message) {return new Result<String>(message);}
}

对返回结果封装

此时我们就可以使用封装类封装统一格式的响应了

import com.mijiu.common.result.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author mijiupro*/
@RestController
@RequestMapping("/test1")
public class Test1Controller {@GetMapping("/hello")public Result<String> hello() {return Result.success("hello world");}
}

我们的接口通常有很多,如果对每个接口都封装属于重复劳动,可以利用AOP技术拦截控制类的返回结果进行封装。

代码如下

import cn.hutool.json.JSONUtil;
import com.mijiu.commom.result.Result;
import io.micrometer.common.lang.NonNullApi;
import io.micrometer.common.lang.Nullable;
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.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;/*** 统一结果封装增强器* @author mijiupro*/
@RestControllerAdvice(basePackages = "com.mijiu.controller")//指定要增强的包
@NonNullApi
public class ResultAdvice implements ResponseBodyAdvice<Object> {/*** 判断是否支持对返回类型的处理** @param returnType    方法参数的类型* @param converterType 转换器的类型* @return 是否支持处理*/@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}/*** 在写入响应体之前对返回结果进行处理和封装** @param body                  返回结果对象* @param returnType            方法参数的类型* @param selectedContentType   响应内容的类型* @param selectedConverterType 转换器的类型* @param request               HTTP 请求对象* @param response              HTTP 响应对象* @return 处理后的返回结果*/@Overridepublic Object beforeBodyWrite(@Nullable Object body, MethodParameter returnType,MediaType selectedContentType, Class selectedConverterType,ServerHttpRequest request, ServerHttpResponse response) {//当返回结果为字符串类型需要单独处理if (body instanceof String) {// 如果返回结果是字符串类型,将其封装为成功的结果对象,并转换为 JSON 字符串return JSONUtil.toJsonStr(Result.success(body));}// 将返回结果封装为成功的结果对象return Result.success(body);}
}

此代码可以兼容任何类型的返回结果对其进行统一封装。

为何遇到方法的返回结果是String类型需要手动转成json返回呢?

解决java.lang.ClassCastException-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_62262918/article/details/136003915?spm=1001.2014.3001.5501

测试封装

现在com.mijiu.controller下的所有控制类的所有方法都会被拦截将返回结果进行统一格式封装。

到这里返回结果统一封装结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/677596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「daily updating」k3s + openfaas serverless bench 踩坑指南持续更新中

OpenFaas从入门到实战 – 踩坑指南 &#xff5c; k3dOpenFaas | deploy your first python function https://blog.alexellis.io/first-faas-python-function/ https://docs.openfaas.com/deployment/kubernetes/ 搭建环境&#xff1a;第一种方法失败&#xff0c;第二种方法…

【SpringBootStarter】自定义全局加解密组件

【SpringBootStarter】 目的 了解SpringBoot Starter相关概念以及开发流程实现自定义SpringBoot Starter(全局加解密)了解测试流程优化 最终引用的效果&#xff1a; <dependency><groupId>com.xbhog</groupId><artifactId>globalValidation-spring…

[职场] 大厂群面的基本题型 #学习方法#其他

大厂群面的基本题型 大厂群面的基本题型 群面&#xff0c;又叫做“无领导小组面试”。历年来是企业校招时&#xff0c;进行大批量刷人的有效方法。流行于互联网、快消、银行、四大等多个行业。因为难度大、情况复杂、淘汰率高&#xff0c;又被称为“死亡面试”。 无领导小组…

CSP-202012-2-期末预测之最佳阈值

CSP-202012-2-期末预测之最佳阈值 【70分思路】 本题的难点还是时间复杂度&#xff0c;暴力枚举会导致时间超限。对于每一个可能的阈值theta&#xff0c;代码都重新计算了整个predict数组&#xff0c;统计预测正确的数目&#xff0c;因为有两个嵌套的循环&#xff0c;使得时间…

计算机网络之一

目录 1.因特网概述 1.1网络、互连网&#xff08;互联网&#xff09;和因特网 1.2.因特网发展的三个阶段 1.3基于ISP的三层架构的因特网 1.4.因特网的组成 2.三种交换方式 2.1电路交换 2.2分组交换 1.因特网概述 1.1网络、互连网&#xff08;互联网&#xff09;和因特网…

Git分支常用指令

目录 1 git branch 2 git branch xx 3 git checkout xx 4 git checkout -b xx 5 git branch -d xx 6 git branch -D xx 7 git merge xx(含快进模式和冲突解决的讲解) 注意git-log: 1 git branch 作用&#xff1a;查看分支 示例&#xff1a; 2 git branch xx 作用&a…

数据结构——5.5 树与二叉树的应用

5.5 树与二叉树的应用 概念 结点的权&#xff1a;大小可以表示结点的重要性 结点的带权路径长度&#xff1a;从树的根到该结&#xff0c;的路径长度&#xff08;经过的边数&#xff09;与该结点权的乘积 树的带权路径长度&#xff1a;树中所有叶结点的带权路径长度之和(WPL) …

蜂鸣器播放提示音音乐(天空之城)

目录 蜂鸣器播放提示音 蜂鸣器播放音乐&#xff08;天空之城&#xff09; 准备工作 主程序 中断函数 上一节讲了蜂鸣器驱动原理和乐理基础知识&#xff0c;这一节开始代码演示&#xff01; 蜂鸣器播放提示音 先创建工程&#xff1a;蜂鸣器播放提示音 把我们之前模块化的…

python 爬虫篇(3)---->Beautiful Soup 网页解析库的使用(包含实例代码)

Beautiful Soup 网页解析库的使用 文章目录 Beautiful Soup 网页解析库的使用前言一、安装Beautiful Soup 和 lxml二、Beautiful Soup基本使用方法标签选择器1 .string --获取文本内容2 .name --获取标签本身名称3 .attrs[] --通过属性拿属性的值标准选择器find_all( name , at…

Sentinel 源码分析

Sentinel源码分析 项目源码 1.Sentinel的基本概念 Sentinel实现限流、隔离、降级、熔断等功能&#xff0c;本质要做的就是两件事情&#xff1a; 统计数据&#xff1a;统计某个资源的访问数据&#xff08;QPS、RT等信息&#xff09;规则判断&#xff1a;判断限流规则、隔离规…

20240210使用剪映识别字幕的时候的GPU占比RX580-RTX4090

20240210使用剪映识别字幕的时候的GPU占比RX580-RTX4090 2024/2/10 17:54 【使用剪映识别不同的封装格式&#xff0c;不同的音视频编码&#xff0c;对GPU的占用率可能会有比较大的不同&#xff01;】 很容易发现在在WIN10下使用剪映的时候&#xff0c;X99RX550组合。 GPU部分&…

【Spring】Bean 的生命周期

一、Bean 的生命周期 Spring 其实就是一个管理 Bean 对象的工厂&#xff0c;它负责对象的创建&#xff0c;对象的销毁等 所谓的生命周期就是&#xff1a;对象从创建开始到最终销毁的整个过程 什么时候创建 Bean 对象&#xff1f;创建 Bean 对象的前后会调用什么方法&#xf…

【Go】三、Go并发编程

并发编程 我们主流的并发编程思路一般有&#xff1a;多进程、多线程 但这两种方式都需要操作系统介入&#xff0c;进入内核态&#xff0c;是十分大的时间开销 由此而来&#xff0c;一个解决该需求的技术出现了&#xff1a;用户级线程&#xff0c;也叫做 绿程、轻量级线程、协…

大厂的供应链域数据中台设计

关注我&#xff0c;紧跟本系列专栏文章&#xff0c;咱们下篇再续&#xff01; 作者简介&#xff1a;魔都技术专家兼架构&#xff0c;多家大厂后端一线研发经验&#xff0c;各大技术社区头部专家博主&#xff0c;编程严选网创始人。具有丰富的引领团队经验&#xff0c;深厚业务架…

庆除夕,比特币两日大涨10%

号外&#xff1a;教链内参2024年1月合订本 今日除夕。昨日今日两天&#xff0c;比特币从43k发力上攻&#xff0c;一度涨超10%至47.7k&#xff0c;以独特的方式给全世界的bitcoiners送去了新春的祝福。 一个新鲜的知识&#xff1a;2023年12月22日&#xff0c;第78届联合国大会协…

JVM 执行引擎

概念 执行class文件中的指令&#xff0c;由解释器编译器组成 补充——Java为什么是半编译半解释型语言 因为Java即有编译器也有解释器&#xff0c;可以用其中一种来运行。 程序执行步骤 解释器与编译器区别 编译器 概念 JIT&#xff08;Just In Time Compiler&#xff09;…

深入探索Java IO:从基础到高级操作全览

深入探索Java IO&#xff1a;从基础到高级操作全览 Java IO一、概览二、磁盘操作三、字节操作实现文件复制装饰者模式 四、字符操作编码与解码String 的编码方式Reader 与 Writer实现逐行输出文本文件的内容 五、对象操作序列化Serializabletransient 六、网络操作InetAddressU…

机器学习系列——(十三)多项式回归

引言 在机器学习领域&#xff0c;线性回归是一种常见且简单的模型。然而&#xff0c;在某些情况下&#xff0c;变量之间的关系并不是线性的&#xff0c;这时候我们就需要使用多项式回归来建模非线性关系。多项式回归通过引入高次项来扩展线性回归模型&#xff0c;从而更好地拟…

【前端】Vue实现网站导航 以卡片形式显示(附Demo)

目录 前言1. html版本2. Vue2.1 Demo12.2 Demo2 前言 单独做一个跳转页面推荐阅读&#xff1a;【前端】实现Vue组件页面跳转的多种方式 但是如果网站多了&#xff0c;推荐卡片式导航&#xff0c;具体可看下文&#xff1a;&#xff08;以图片显示显示各个网站&#xff0c;图片…

MySQL-视图(VIEW)

文章目录 1. 什么是视图&#xff1f;2. 视图 VS 数据表3. 视图的优点4. 视图相关语法4.1 创建视图4.2 查看视图4.3 修改视图4.4 删除视图4.5 检查选项 5. 案例6. 注意事项 1. 什么是视图&#xff1f; MySQL 视图&#xff08; View&#xff09;是一种虚拟存在的表&#xff0c;同…