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

Spring Boot 统一功能处理(二)

        本篇主要介绍Spring Boot统一功能处理中的统一数据返回格式。

目录

一、定义统一的返回类

 二、配置统一数据格式

三、测试配置效果

四、统一格式返回的优点 

五、源码角度解析String问题


一、定义统一的返回类

在我们的接口在处理请求时,返回的结果可以说是参差不齐,既可以是一个String类型的数据,又可以是一个Integer类型的数据,这样未免会显得我们的代码很不规范,并且这种不规范的代码还会增加前后端之间的交流成本。因此,我们可以设计一个统一的类来作为所有接口的返回结果。这个统一的类通常需要包含以下三个部分:

  • code:由我们自己定义的一个状态码
  • msg:响应结果的描述
  • data:响应的数据

下面我们通过代码来具体来实现一下这个类 :

这里可以使用泛型来作为data的参数,毕竟返回的数据类型是多种多样的。

下面我们来改造一下上一篇中所定义的login方法:

这里的状态码200代表请求成功,-1代表失败。

仔细观察可以发现,这串代码其实是有点冗余的,每次返回数据时都得设置一次Result的三个属性。因此,我们还可以对Result进行一些优化,具体如下:

这里我们将设置Result属性的代码进行了封装,因此接口在返回数据时,直接调用这里的方法即可(由于fail表示请求失败,请求失败了通常不会有返回的数据,因此fail没有设置data参数)。接下来我们再优化一下前面的login方法:

 

这样代码就看着简洁多了。

 二、配置统一数据格式

虽然我们这里已经定义了统一的数据返回类Result,但我们并不能保证所有接口都会以这个类作为返回结果,因此我们还需要借助Spring 来配置一下统一的数据返回格式。

首先我们需要创建一个类来实现ResposeBodyAdvice:

然后重写两个方法:

 其中supports是用来选择要进行统一返回处理的方法,如果直接返回true那就是所有接口都会进行这个统一处理,如果不想全部都统一处理,也可以通过下面的方式获取相关的类或者方法,并以此来判定是否要统一处理:

         //获取执行返回操作的类Class<?> declaringClass = returnType.getMethod().getDeclaringClass();//获取执行返回操作的方法Method method = returnType.getMethod();

 另一个方法beforeBodyWrite是对返回的数据具体进行统一处理的逻辑,其中body就是我们在接口里返回的数据。这里已经写好了一个大体逻辑,如果是我们前面定义的返回类直接返回,如果不是就把body封装到返回类里再返回。

最后我们还需要再类上加上一个@ControllerAdvice注解:

通过这个注解的实现可以发现,他是@Component的衍生注解,因此加了这个注解的类也会被加到Spring容器中。并且可以发现@ControllerAdvice还多了很多别的功能,这里就不过多介绍了。 

三、测试配置效果

接下来我们通过postMan来测试一下配置的效果。

我们先测试一下返回类型为Result的接口:

postMan请求后的结果:

通过结果可以发现响应符合我们的统一要求。

然后我们创建一个返回值不为Result的接口:

通过PostMan来访问可以发现结果也是符合预期的:

 

然后我们再试试返回集合:

通过postMan来访问一下可以发现结果正常:

接下来我们再看看返回对象,

首先我们创建一个User类然后对这个User类进行返回:

通过PostMan可以发现结果正确。

最后我们再来看一下返回类型是String类型:

 通过PostMan来访问可以发现报错了:

 我们再去后端看一下:

可以发现后端报了一个类型不匹配异常,至于为什么会报这个异常,后面会解释,我们先来看看解决方法。

首先我们得在项目中引入Jackson依赖,由于Spring web中内置了这个依赖,因此不需要自己特意去引入Jackson直接引入Spring web依赖即可。

然后使用Jackson提供的ObjectMapper类,由于Spring中已经自动添加了这个类的Bean,我们可以直接注入使用,然后利用Object将返回的Result转为字符串,由于使用objectmapper转换成字符串需要处理一个异常,因此在这里可以加上@SneakyThrows(使用这个注解可以将受检查异常转为非受检查异常(运行时异常),从而使我们不再需要去处理异常信息)具体代码如下:

我们再通过postMan来测试一下,可以发现,这次没有报错了,但返回类型不在是Json,而是text了:

四、统一格式返回的优点 

为什么要这么大费周章设置一个统一返回的格式呢。因为它具有如下一些优点:

  • 方便前端接受和处理后端响应的数据
  • 降低了前后端的沟通成本
  • 有利于项目统一数据的维护和修改
  • 有利于后端进行统一的规范和标准制定,以免后端返回一些乱七八糟的数据
五、源码角度解析String问题

接下来我们从源码角度来解释一下为什么当返回的数据类型是String时在进行统一返回处理时会出现类型不匹配异常。

Spring mvc在使用时,会自动注册一些自带的HttpMessageConverter来处理返回的数据,注册的先后顺序为:

ByteArrayHttpMessageConverter、StringHttpMessageConverter、SourceHttpMessageCoverter、AllencompassingFormHttpMessageConverter

在注册AllencompassingFormHttpMessageConverter时会去引入一些根据项目依赖去引入其它的拓展HttpMessageConvert,例如,项目中如果添加了Jackson则会引入MappingJackson2HttpMessageConverter。

这些HttpMessageConverter会按照注册的顺序形成一条调用链,如果有数据返回时,spring会对这条链按照先后顺序进行遍历 ,如果找到能处理当前返回数据的数据类型的HttpMessageConverter则会直接使用这个HttpMessageConverter来处理,当我们返回的数据类型是非String时,例如集合,对象等,由于前面的几个HttpMessageConverter都不能使用,所以会使用前面最后引入的MappingJackson2HttpMessageConverter来处理数据,而当返回的是String时,则能够使用StringHttpMessageConverter来进行处理,而StringHttpMessageConverter又在链中靠前的位置,因此在返回String时会使用StringHttpMessageConverter来进行处理。

接下来我们进到HttpMessageConverter处理数据的具体方法writeWithHttpMessageConvert来看一下:

打开方法实现往下翻可以看到这样一行代码

仔细观察可以发现这行代码就是在调用我们前面所设置beforeBodyWrite方法,由此可以推断出在执行完这行代码后body由String转换为我们前面所设置的Result类型了。

继续往下翻可以发现这样一行代码

 由于我们返回的是String,所以这里的converter应该是StringHttpMessageConverter类型的,我们进到write(这里使用的是StringHttpMessageConverter父类AbstarctHttpMessageConverter实现的write方法)方法来看一下:

可以发现在这里使用的是泛型参数t来接收body,因此没有出现类型匹配问题,在这个方法里调用了一个addDefaultHeaders方法,由于StringHttpMessageConverter重写了这个方法,因此在这里使用的是StringHttpMessageConverter实现的这个方法,我们进到里面去看一下:

进到里面可以发现这个方法采用的是String类型的s来接收我们前面的t,也就是body,但body已经在前面通过我们定义的beforeBdoyWriter方法由String转换为了Result类型,因此这里在接收参数时,发生了类型不匹配异常,从而也就产生了前面类型不匹配的报错。

相关文章:

Spring Boot 统一功能处理(二)

本篇主要介绍Spring Boot统一功能处理中的统一数据返回格式。 目录 一、定义统一的返回类 二、配置统一数据格式 三、测试配置效果 四、统一格式返回的优点 五、源码角度解析String问题 一、定义统一的返回类 在我们的接口在处理请求时&#xff0c;返回的结果可以说是参…...

Flutter开发基础之动画专题

Flutter开发基础之动画专题 动画设计的作用是让UI界面更流畅、直观&#xff0c;能够有效的提升用户体验。 在Flutter开发中&#xff0c;动画分为多个方面&#xff1a; 基础动画、页面交互动画、绘图动画、矩阵变换等。 基本动画 常用的基本动画有透明度动画、缩放动画、旋转动…...

PHP 图片裁剪类封装

PHP工具类 图片裁剪类封装 <?php namespace App\Utils;/*** 图片裁剪工具类* author 田小涛* date 2020年7月23日* comment**/ class ImageCropUtils {private $sImage;private $dImage;private $src_file;private $dst_file;private $src_width;private $src_height;priv…...

Android 14.0 SystemUI修改状态栏电池图标样式为横屏显示

1.概述 在14.0的系统rom产品定制化开发中,对于原生系统中SystemUId 状态栏的电池图标是竖着显示的,一般手机的电池图标都是横屏显示的 可以觉得样式挺不错的,所以由于产品开发要求电池图标横着显示和手机的样式一样,所以就得重新更换SystemUI状态栏的电池样式了 如图: 2.S…...

FPGA:图像数字细节增强算法(工程+仿真+实物,可用毕设)

目录 日常唠嗑一、视频效果二、硬件及功能1、硬件选择2、功能3、特点 未完、待续……四、工程设计五、板级验证六、工程获取 日常唠嗑 有2个多月没写文章了&#xff0c;又是老借口&#xff1a;“最近实在是很忙”&#x1f923;&#xff0c;不过说真&#xff0c;确实是比较忙&am…...

Android netty的使用

导入netty依赖 implementation io.netty:netty-all:4.1.107.Final使用netty 关闭netty /*** 关闭*/private void closeSocket() {LogUtils.i(TAG, "closeSocket");if (nettyManager ! null) {nettyManager.close();nettyManager null;}if (nettyExecutor ! null) {…...

苹果电脑启动磁盘是什么意思 苹果电脑磁盘清理软件 mac找不到启动磁盘 启动磁盘没有足够的空间来进行分区

当你一早打开苹果电脑&#xff0c;结果系统突然提示&#xff1a; “启动磁盘已满&#xff0c;需要删除部分文件”。你会怎么办&#xff1f;如果你认为单纯靠清理废纸篓或者删除大型文件就能释放你的启动磁盘上的空间&#xff0c;那就大错特错了。其实苹果启动磁盘的清理技巧有很…...

【Java SE】多态

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. 多态1.1 多态是什么1.2 多态的意义1.3 多态的实现条件 2. 重写2.1 重写的概念2.2 重写的规则2.3 重写与重…...

Yarn vs npm的大同小异Yarn是什么?

Yarn vs npm的大同小异&Yarn是什么&#xff1f; 一、Yarn、npm是什么&#xff1f;二、Yarn vs npm&#xff1a;特性差异总结 一、Yarn、npm是什么&#xff1f; npm是Node.js的包管理器&#xff0c;是由Chris Korda维护。 npm,它全称为Node Package Manager&#xff0c;是…...

1.Godot引擎|场景|节点|GDS|介绍

Godot介绍 Godot是一款游戏引擎 可以通过在steam商城免费下载 初学者和编程基础稍差的推荐学习使用GDScript&#xff0c;和python有些相似 Godot节点 Godot的开发思想——围绕节点 节点的特征与优势 最常用基本的开发组件大部分都具有具体的功能&#xff0c;如图片&#xf…...

springboot3 redis 实现分布式锁

分布式锁介绍 分布式锁是一种在分布式系统中用于控制不同节点上的进程或线程对共享资源进行互斥访问的技术机制。 在分布式环境中&#xff0c;多个服务可能同时访问和操作共享资源&#xff0c;如数据库、文件系统等。为了保持数据的一致性和完整性&#xff0c;需要确保在同一…...

2024年第十四届MathorCup数学应用挑战赛A题思路分享(妈妈杯)

A题 移动通信网络中PCI规划问题 物理小区识别码(PCI)规划是移动通信网络中下行链路层上,对各覆盖小区编号进行合理配置,以避免PCI冲突、PCI混淆以及PCI模3干扰等现象。PCI规划对于减少物理层的小区间互相干扰(ICI),增加物理下行控制信道(PDCCH)的吞吐量有着重要的作用,尤其…...

运动听歌哪款耳机靠谱?精选五款热门开放式耳机

随着人们对运动健康的重视&#xff0c;越来越多的运动爱好者开始关注如何在运动中享受音乐。开放式蓝牙耳机凭借其独特的设计&#xff0c;成为了户外运动的理想选择。它不仅让你在运动时能够清晰听到周围环境的声音&#xff0c;保持警觉&#xff0c;还能让你在需要时与他人轻松…...

Kubernetes学习笔记12

k8s核心概念&#xff1a;控制器&#xff1a; 我们删除Pod是可以直接删除的&#xff0c;如果生产环境中的误操作&#xff0c;Pod同样也会被轻易地被删除掉。 所以&#xff0c;在K8s中引入另外一个概念&#xff1a;Controller&#xff08;控制器&#xff09;的概念&#xff0c;…...

Qt Designer 控件箱中的控件介绍及布局比列分配

控件箱介绍 Qt Designer的控件箱&#xff08;Widget Box&#xff09;包含了各种常用的控件&#xff0c;用户可以通过拖放的方式将这些控件添加到窗体设计器中&#xff0c;用于构建用户界面。以下是一些常见控件箱中的控件及其功能的讲解&#xff1a; 1.基本控件&#…...

蓝桥集训之三国游戏

蓝桥集训之三国游戏 核心思想&#xff1a;贪心 将每个事件的贡献值求出 降序排序从大到小求和为正是即可 #include <iostream>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int N 100010;int a[N],b[N],c[N];…...

MySQL知识整理

MySQL知识整理 基础第一讲&#xff1a;基础架构&#xff1a;一条SQL查询语句是如何执行的&#xff1f;架构尽量减少长连接的原因和方案为什么尽量不要依赖查询缓存 索引第四讲&#xff1a;深入浅出索引&#xff08;上&#xff09;第五讲&#xff1a;深入浅出索引&#xff08;下…...

代码随想录算法训练营第36天| 435. 无重叠区间、 763.划分字母区间*、56. 合并区间

435. 无重叠区间 力扣题目链接 代码 示例代码 class Solution { public:// 按照区间右边界排序static bool cmp (const vector<int>& a, const vector<int>& b) {return a[1] < b[1];}int eraseOverlapIntervals(vector<vector<int>>&a…...

SpringBoot整合Nacos

文章目录 nacosnacos下载nacos启动nacos相关配置demo-dev.yamldemo-test.yamluser.yaml 代码pom.xmlUserConfigBeanAutoRefreshConfigExampleValueAnnotationExampleDemoApplicationbootstrap.yml测试结果补充.刷新静态配置 nacos nacos下载 下载地址 一键傻瓜试安装即可,官…...

vue3 浅学

一、toRefs 问题: reactive 对象取出的所有属性值都是⾮响应式的 解决: 利⽤ toRefs 可以将⼀个响应式 reactive 对象的所有原始属性转换为 响应式的 ref 属性 二、hook函数 将可复⽤的功能代码进⾏封装&#xff0c;类似与vue2混⼊。 三、ref&#xff1a;获取元素或者组件 let …...

三小时使用鸿蒙OS模仿羊了个羊,附源码

学习鸿蒙arkTS语言&#xff0c;决定直接通过实践的方式上手&#xff0c;而不是一点点进行观看视频再来实现。 结合羊了个羊的开发思路&#xff0c;准备好相应的卡片素材后进行开发。遇到了需要arkTS进行解决的问题&#xff0c;再去查看相应的文档。 首先需要准备卡片对应的图片…...

如何使用 ArcGIS Pro 制作热力图

热力图是一种用颜色表示数据密度的地图&#xff0c;通常用来显示空间分布数据的热度或密度&#xff0c;我们可以通过 ArcGIS Pro 来制作热力图&#xff0c;这里为大家介绍一下制作的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的POI数…...

SpringBoot之集成Redis

SpringBoot之集成Redis 一、Redis集成简介二、集成步骤2.1 添加依赖2.2 添加配置2.3 项目中使用 三、工具类封装四、序列化 &#xff08;正常都需要自定义序列化&#xff09;五、分布式锁&#xff08;一&#xff09;RedisTemplate 去实现场景一&#xff1a;单体应用场景二&…...

mybatis-plus与mybatis同时使用别名问题

在整合mybatis和mybatis-plus的时候发现一个小坑&#xff0c;单独使用mybatis&#xff0c;配置别名如下&#xff1a; #配置映射文件中指定的实体类的别名 mybatis.type-aliases-packagecom.jk.entity XML映射文件如下&#xff1a; <update id"update" paramete…...

MySQL基础知识——MySQL日志

一条查询语句的执行过程一般是经过连接器、 分析器、 优化器、 执行器等功能模块&#xff0c; 最后到达存储引擎。 那么&#xff0c; 一条更新语句的执行流程又是怎样的呢&#xff1f; 下面我们从一个表的一条更新语句进行具体介绍&#xff1a; 假设这个表有一个主键ID和一个…...

uniapp 地图分幅网格生成 小程序基于map组件

// 获取小数部分 const fractional function(x) {x Math.abs(x);return x - Math.floor(x); } const formatInt function(x, len) {let result x;len len - result.length;while (len > 0) {result 0 result;len--;}return result; }/*** 创建标准分幅网格* param …...

python项目练习——22、人脸识别软件

功能分析: 人脸检测: 识别图像或视频中的人脸,并标记出人脸的位置和边界框。 人脸识别: 识别人脸的身份或特征,通常使用已知的人脸数据库进行训练,然后在新的图像或视频中识别出人脸并匹配到相应的身份。 表情识别: 识别人脸的表情,如高兴、悲伤、愤怒等,并给出相应…...

Linux中账号登陆报错access denied

“Access denied” 是一个权限拒绝的错误提示&#xff0c;意味着用户无法获得所请求资源的访问权限。出现 “Access denied” 错误的原因可以有多种可能性&#xff0c;包括以下几种常见原因&#xff1a; 错误的用户名或密码&#xff1a;输入的用户名或密码不正确&#xff0c;导…...

python语言之round(num, n)小数四舍五入

文章目录 python round(num, n)小数四舍五入python round(num, n)基础银行家舍入&#xff08;Bankers Rounding&#xff09;利息被银行四舍五入后&#xff0c;你到底是赚了还是亏了&#xff1f; python小数位的使用decimal模块四舍五入(解决round 遇5不进) python round(num, n…...

安全风险攻击面管理如何提升企业网络弹性?

从研究人员近些年的调查结果来看&#xff0c;威胁攻击者目前非常善于识别和利用最具有成本效益的网络入侵方法&#xff0c;这就凸显出了企业实施资产识别并了解其资产与整个资产相关的安全态势的迫切需要。 目前来看&#xff0c;为了在如此复杂的网络环境中受到最小程度上的网络…...

查公司信息的网站/百度网盘登录首页

这里写自定义目录标题找出数组中重复的数字。在一个长度为 n 的数组 nums 里的所有数字都在 0&#xff5e;n-1 的范围内。数组中某些数字是重复的&#xff0c;但不知道有几个数字重复了&#xff0c;也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 示例 1&…...

物流网站开题报告/seo搜索引擎是什么

官方的说法是 MySQL 4.1 and up uses an authentication protocol based on a password hashing algorithm that is incompatible with that used by older clients. ..... 如果你升级mysql到4.1以上版本后遇到以上问题,请先确定你的mysql client 是4.1或者更高版本.(WINDOWS下…...

做网站的技术支持/网站排名优化软件哪家好

什么是RDD&#xff1a;RDD叫做分布式数据集&#xff0c;是Spark最基本的数据抽象&#xff0c;代码中是一个抽象类&#xff0c;它代表的是一个不可变、可分区、里面的元素可并行计算的集合。RDD里面封装的是计算逻辑。RDD的属性&#xff1a;1. 一个分区(Partition),即数据集的基…...

什么企业做网站/国家卫健委最新疫情报告

Python中plot() 淘宝历史价格&#xff0c;js chrome 插件 文档&#xff1a;Python中plot() 淘宝历史价格&#xff0c;js chro… 链接&#xff1a;http://note.youdao.com/noteshare?id2f626c689f0b2f8bbad7b464155d9078&sub6FC95351EB414B97847B03904FADBB10 添加链接描述…...

做网站 怎么选择公司/2022真实新闻作文400字

最近看Google图书&#xff0c;令人感到困惑的无非是无法自由的地下载其图片。以至于网上充斥着Google图书下载器。查看源代码&#xff0c;着实让人困惑不已。还好有IE Developer Tools&#xff0c;才大致将其UI结构搞的一知半解。至于图片的下载这倒是需要在仔细研究下。顺便做…...

广州天河网站建设/私人做网站

后端统计函数 函数 返回类型描述pg_stat_get_backend_idset()int设置当前活动的后端ID号pg_stat_get_backend_activity(interger)text后端最近查询文本pg_stat_get_backend_activity_start(interger)timestamp with time zone最近查询开始时间pg_stat_get_backend_client…...