SpringBoot实现统一返回接口(除AOP)
起因
关于使用AOP去实现统一返回接口在之前的博客中我们已经实现了,但我突然突发奇想,SpringBoot中异常类的统一返回好像是通过@RestControllerAdvice
这个注解去完成的,那我是否也可以通过这个注解去实现统一返回接口。
正文
这个方法主要是通过@ControllerAdvice
+ ResponseBodyAdvice
实现统一返回结果。其实本质来说和aop实现是相通的明白一个另一个就非常好理解了。
(Result 的代码我就不在这边重复贴了,读者可以去我直接用AOP实现的博客中拿)
自定义注解
import com.study.project.common.BaseResponse;
import com.study.project.common.ResultCode;import java.lang.annotation.*;import static com.study.project.common.ResultCode.SUCCESS;/*** @date 2023/2/18*/
@Documented
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface FunctionResult {String value() default "";//默认code为成功ResultCode code() default SUCCESS;
}
自定义一个响应拦截
import com.study.project.annotation.FunctionResult;
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;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;/*** @author Chengming.Zhang* @date 2023/2/18* ResponseBodyAdvice主要是对加了@RestController(也就是@Controller+@ResponseBody)注解的处理器将要返回的值进行增强处理。*其实也就是采用了AOP的思想,对返回值进行一次修改。*/
@RestControllerAdvice
public class FunctionResponseBodyAdvice implements ResponseBodyAdvice {//判断当前类上是否有@FunctionResultprotected boolean isFunctionResult(MethodParameter returnType) {/*** getContainingClass() 获取当前类的信息* isAnnotationPresent 判断当前类上是否存在某个注解*/Class<?> containingClass = returnType.getContainingClass();boolean annotationPresent = containingClass.isAnnotationPresent(FunctionResult.class);Annotation[] annotations = containingClass.getAnnotations();return returnType.getContainingClass().isAnnotationPresent(FunctionResult.class);}@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return isFunctionResult(returnType);}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {Method method = returnType.getMethod();Class<?> methodReturnType = method.getReturnType();//判断是否为void的方法if (methodReturnType.equals(void.class)) {return body;}//判断当前方法是否有@FunctionResult注解,如果没有则全部按照成功返回,如果有则根据具体指定的返回码以及返回内容返回FunctionResult result = returnType.getMethod().getAnnotation(FunctionResult.class);if (result == null) {return new BaseResponse(ResultCode.SUCCESS, body);}ResultCode code = result.code();return new BaseResponse(result.code(), body);}
}
controller类
import com.study.project.annotation.FunctionResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;/*** @date 2023/2/4*/
@FunctionResult
@RestController
public class TestController {@RequestMapping("/test5")public int test5(){return 1;}@RequestMapping("/test6")public void test6(){System.err.println("test6");}
}
测试
你是不是以为代码已经结束?
其实这个代码是有问题hhhhh,当接口的返回类型是String的时候就会提示报错
看控制台的报错信息发现是接口的返回参数转换的时候报错了,于是我们根据控制台上的报错信息进行断点排查
首先我们找到控制台中的第一行的报错类StringHttpMessageConverter.java
中的addDefaultHeaders
方法,发这个方法其实是重新了他父类的AbstractHttpMessageConverter
的方法
在AbstractHttpMessageConverter
中的方法Result的参数是T,但是StringHttpMessageConverter
在重写的时候将其转为了String,因此当ResponseBodyAdvice
返回Result格式的时候就会报错,所以我们就需要在ResponseBodyAdvice
中需要单独处理一下String类型。
完整代码
import cn.hutool.json.JSONUtil;
import com.study.project.annotation.FunctionResult;
import jdk.nashorn.internal.objects.annotations.Function;
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.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import java.lang.annotation.Annotation;
import java.lang.reflect.Method;/*** @author Chengming.Zhang* @date 2023/2/18* ResponseBodyAdvice主要是对加了@RestController(也就是@Controller+@ResponseBody)注解的处理器将要返回的值进行增强处理。*其实也就是采用了AOP的思想,对返回值进行一次修改。*/
@RestControllerAdvice
public class FunctionResponseBodyAdvice implements ResponseBodyAdvice {//判断当前类上是否有@FunctionResultprotected boolean isFunctionResult(MethodParameter returnType) {/*** getContainingClass() 获取当前类的信息* isAnnotationPresent 判断当前类上是否存在某个注解*/Class<?> containingClass = returnType.getContainingClass();boolean annotationPresent = containingClass.isAnnotationPresent(FunctionResult.class);Annotation[] annotations = containingClass.getAnnotations();return returnType.getContainingClass().isAnnotationPresent(FunctionResult.class);}@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return isFunctionResult(returnType);}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {Method method = returnType.getMethod();Class<?> methodReturnType = method.getReturnType();if (methodReturnType.equals(void.class)) {return body;}//判断当前方法是否有@FunctionResult注解,如果没有则全部按照成功返回,如果有则根据具体指定的返回码以及返回内容返回FunctionResult result = returnType.getMethod().getAnnotation(FunctionResult.class);if (result == null) {if (body instanceof String) {return JSONUtil.toJsonStr(new BaseResponse(ResultCode.SUCCESS, body));}return new BaseResponse(ResultCode.SUCCESS, body);}if (body instanceof String) {return JSONUtil.toJsonStr(new BaseResponse(result.code(), body));}return new BaseResponse(result.code(), body);}
}
相关文章:
![](https://img-blog.csdnimg.cn/ffde03220a884be5ad765210536b916f.png)
SpringBoot实现统一返回接口(除AOP)
起因 关于使用AOP去实现统一返回接口在之前的博客中我们已经实现了,但我突然突发奇想,SpringBoot中异常类的统一返回好像是通过RestControllerAdvice 这个注解去完成的,那我是否也可以通过这个注解去实现统一返回接口。 正文 这个方法主要…...
![](https://www.ngui.cc/images/no-images.jpg)
ChatGpt - 基于人工智能检索进行论文写作
摘要 ChatGPT 是一款由 OpenAI 训练的大型语言模型,可用于各种自然语言处理任务,包括论文写作。使用 ChatGPT 可以帮助作者提高论文的语言流畅度、增强表达能力和提高文章质量。在写作过程中,作者可以使用 ChatGPT 生成自然语言的段落、句子、单词或者短语,作为启发式的写…...
![](https://img-blog.csdnimg.cn/img_convert/1b3ea23a7bf105ebaa0cc48157b6117d.png)
实例三:MATLAB APP design-多项式函数拟合
一、APP 界面设计展示 注:在左侧点击数据导入,选择自己的数据表,如果数据导入成功,在右侧的空白框就会显示数据导入成功。在多项式项数右侧框中输入项数,例如2、3、4等,点击计算按钮,右侧坐标框就会显示函数图像,在平均相对误差下面的空白框显示平均相对误差。...
![](https://www.ngui.cc/images/no-images.jpg)
springboot多种方式注入bean获取Bean
springboot动态注入bean1、创建Bean(demo)2、动态注入Bean3、通过注解注入Bean4、通过config配置注入Bean5、通过Import注解导入6、使用FactoryBean接口7、实现BeanDefinitionRegistryPostProcessor接口1、创建Bean(demo) Data public class Demo(){private String name;publi…...
![](https://img-blog.csdnimg.cn/img_convert/03c34b0ef08fcf773f62436d4527073b.png)
Markdown及其语法详细介绍(全面)
文章目录一、基本语法1.标题2.段落和换行3.强调4.列表5.链接6.图片7.引用8.代码9.分割线10表格二、扩展语法1.标题锚点标题 {#anchor}2.脚注3.自动链接4.任务列表5.删除线6.表情符号7.数学公式三、Markdown 应用1.文档编辑2.博客写作3.代码笔记四、常见的工具和平台支持 Markdo…...
![](https://img-blog.csdnimg.cn/img_convert/f1ac9f49e401671fe687b5f8b351e47e.png)
在Linux和Windows上安装sentinel-1.8.5
记录:380场景:在CentOS 7.9操作系统上,安装sentinel-1.8.5。在Windows上操作系统上,安装sentinel-1.8.5。Sentinel是面向分布式、多语言异构化服务架构的流量治理组件。版本:JDK 1.8 sentinel-1.8.5 CentOS 7.9官网地址…...
![](https://www.ngui.cc/images/no-images.jpg)
面试攻略,Java 基础面试 100 问(十)
StringBuffer、StringBuilder、String区别 线程安全 StringBuffer:线程安全,StringBuilder:线程不安全。 因为 StringBuffer 的所有公开方法都是 synchronized 修饰的,而 StringBuilder 并没有 synchronized 修饰。 StringBuf…...
![](https://img-blog.csdnimg.cn/4faeb281d50d49878b3ceccc8fbad66c.png)
Zero-shot(零次学习)简介
zero-shot基本概念 首先通过一个例子来引入zero-shot的概念。假设我们已知驴子和马的形态特征,又已知老虎和鬣狗都是又相间条纹的动物,熊猫和企鹅是黑白相间的动物,再次的基础上,我们定义斑马是黑白条纹相间的马科动物。不看任何斑…...
![](https://img-blog.csdnimg.cn/img_convert/db0ad53298bd140736b6b9f22c70206c.png)
51单片机简易电阻电感电容RLC测量仪仿真设计
51单片机简易电阻电感电容RLC测量仪仿真( proteus仿真程序讲解视频) 仿真图proteus7.8及以上 程序编译器:keil 4/keil 5 编程语言:C语言 设计编号:S0040 51单片机简易电阻电感电容RLC测量仪仿真51单片机最小系统的相关知识复位…...
![](https://img-blog.csdnimg.cn/1d263870538948119a178c4e90c60202.png)
[软件工程导论(第六版)]第6章 详细设计(课后习题详解)
文章目录1 假设只有SEQUENCE和DO-WHILE两种控制结构,怎样利用它们完成 IF THEN ELSE操作?2 假设只允许使用SEQUENCE和IF-THEN-ELSE两种控制结构,怎样利用它们完成DO WHILE操作?3 画出下列伪码程序的程序流程图和盒图:4…...
![](https://img-blog.csdnimg.cn/img_convert/aca738e3197c44c8bfee5453d88ed2cd.png)
【2.19】算法题2:贪心算法、动态规划、分治
题目:给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。方法一:贪心算法原理:若当前指针所指元素之前的和小…...
![](https://img-blog.csdnimg.cn/0ca47fe9a69d48af89f61117b80c1aa7.png)
【Redis】Redis 发布订阅通信模式 ( 发布订阅模式 | 订阅频道 | 发布消息 | 接收消息 )
文章目录一、发布订阅模式二、订阅频道三、发布消息四、接收消息一、发布订阅模式 Redis 中 存在一种 发布订阅 消息通信模式 : 消息发布者 : 负责发送消息 , 订阅者需要订阅该发布者频道 ;消息订阅者 : 负责接收消息 ; 订阅者 先 订阅 发布者频道 , 当 发布者 发布消息时 , …...
![](https://img-blog.csdnimg.cn/img_convert/be9371af6a559b24dfbe0f10be84c644.png)
VNCTF 2023复现
文章目录象棋王子电子木鱼BabyGo象棋王子 签到题,直接在源码中找就ok。 找到一处编码,在控制台输出。 flag为:flag{w3lc0m3_t0_VNCTF_2023~~~} 电子木鱼 需要先理清代码逻辑。 存在三个路由。 一:/路由用来查看当前的功德数量…...
![](https://img-blog.csdnimg.cn/img_convert/c2ea81d9b359a44ffff8b61f3d35a149.jpeg)
python基础知识有哪些需要背(记住是基础知识)我是初学者
大家好,小编来为大家解答以下问题,一个有趣的事情,一个有趣的事情,今天让我们一起来看看吧! 1、python基础知识有哪些需要背(记住是基础知识)我是初学者 或看好Python的广阔前景,或…...
![](https://www.ngui.cc/images/no-images.jpg)
Linux下TCP连接断开后不释放的解决办法
问题:在开发测试时发现断开与服务器端口后再次连接时拒绝连接。 分析:服务器上查看端口占用情况,假设端口为8888。 netstat -anp |grep 8888 发现端口8888端口显示被占用(ip为本机ip确定是上次连接)且状态为ESTABLI…...
![](https://www.ngui.cc/images/no-images.jpg)
1.关于嵌入式开发软件工程师的理解
学习嵌入式软件开发,首先要学会使用工具, 包括各种语言,C语言、FPGA、C等各种工具软件,各种芯片开发的IDE环境各种操作系统,Vxworks、Linux、Freertos等计算机基础,基本的框架结构,网络通信等编…...
![](https://www.ngui.cc/images/no-images.jpg)
1760字,让你拿捏 [‘列表‘]
如约而至,紧接着第一篇文章,小编将会陆续把自己精心做的全套Python笔记依次发放给大家,便于大家学习Python、期末备考、巩固基础等(这几期是公众号小插曲,后期发放编程技术的话主要还是会围绕Java来展开,感谢小伙伴们的…...
![](https://www.ngui.cc/images/no-images.jpg)
A562基于android的养老APP
需求信息: 1:家庭信息管理,包括家庭成员基本情况、性别、年龄、关系、工作单位、联系方式(手机号码、微信等); 2:个人健康数据管理,包括姓名、性别、年龄、关系、原工作单位、联系方式(手机号码…...
![](https://img-blog.csdnimg.cn/img_convert/27043b1d759ab08c72e163d174c9d0de.png)
java面试题-并发基础
1.多线程的出现是要解决什么问题的? 本质什么?提高程序性能:单线程程序只能按照固定的顺序依次执行每个任务,无法同时处理多个任务。多线程技术可以在同一时间内执行多个任务,从而提高程序的运行效率和响应速度。提高程序的并发性ÿ…...
![](https://www.ngui.cc/images/no-images.jpg)
用纯C语言实现3D空间中的点坐标转化为屏幕二维点坐标,包含主视图、侧视图、俯视图、正等轴投影
要实现3D空间中的点坐标转换为屏幕二维点坐标,需要进行透视变换和投影变换。以下是一些基本的思路和示例代码,可以用于实现主视图、侧视图、俯视图、正等轴投影。 1. 主视图投影 主视图投影是指以一个点作为视点,从一个方向观察物体&#x…...
![](https://www.ngui.cc/images/no-images.jpg)
.sh脚本文件的执行方式
方法1: ./xxx.sh方法2: source xxx.sh方法3: bash xxx.sh方法4: sh xxx.sh初识shell,学习并记录...
![](https://img-blog.csdnimg.cn/2021072514364380.png)
Android 基础知识4-2.5View与VIewGroup的概念、关系与区别
1.概念: Android里的图形界面都是由View和ViewGroup以及他们的子类构成的: View:所有可视化控件的父类,提供组件描绘和时间处理方法 ViewGroup: View类的子类,可以拥有子控件,可以看作是容器 Android UI中的控件都是…...
![](https://www.ngui.cc/images/no-images.jpg)
【ESP 保姆级教程】玩转巴法云篇① ——初识巴法云
忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-02-19 ❤️❤️ 本篇更新记录 2023-02-19 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…...
![](https://img-blog.csdnimg.cn/4170c114015940b0acf1c1ab81f42270.png)
Python学习-----模块3.0(正则表达式-->re模块)
目录 前言: 导入模块 1.re.match() 函数 (1)匹配单个字符 (2)匹配多个字符 (3) 匹配开头和结尾 2.re.search() 函数 3.re.findall() 函数 4.re.finditer() 函数 5.re.split() 函数 6.re.sub() 函数 7.re.sub…...
![](https://img-blog.csdnimg.cn/40074eed0a7c47bea384eed43c0deef2.png)
JSP中http与内置对象学习笔记
本博文讲述jsp客户端与服务器端的http、jsp内置对象与控制流和数据流实现 1.HTTP请求响应机制 HTTP协议是TCP/IP协议中的一个应用层协议,用于定义客户端与服务器之间交换数据的过程 1.1 HTTP请求 HTTP请求由请求行、消息报头、空行和请求数据4部分组成。 请求行…...
![](https://img-blog.csdnimg.cn/img_convert/7829dfacca75fa0192455ebd1d2a3e9d.jpeg)
Windows Server 2016远程桌面配置全过程
镜像下载 系统镜像网址 本次下载的是 Windows Server 2016 (Updated Feb 2018) (x64) - DVD (Chinese-Simplified) 远程桌面配置 Step 1 在开始菜单搜索服务,打开服务器管理器,点击右上角的管理按钮 Step 2 添加角色控制,点击下一步 S…...
![](https://img-blog.csdnimg.cn/dbab8b9a9f3f40d99f98d2b4cc289845.png)
SPI通讯简介
一、基本概念 SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,主要应用在EEPROM,FLASH,实时时钟,AD转换器,多MCU间通讯等等,SPI端口可以在多主器件…...
![](https://www.ngui.cc/images/no-images.jpg)
Python 迭代器
迭代器协议 对象必须提供一个 next() 方法,执行该方法要么迭代下一项,要么就引起一个 StopIteration异常以终止迭代(只能往后不能往前)—— 迭代器协议 协议是一种约定,可迭代对象实现了迭代器协议(for、…...
![](https://img-blog.csdnimg.cn/63a0588727c34154a238312ecec9a4aa.png)
Python语言零基础入门教程(二十七)
Python OS 文件/目录方法 Python语言零基础入门教程(二十六) 61、Python os.utime() 方法 概述 os.utime() 方法用于设置指定路径文件最后的修改和访问时间。 在Unix,Windows中有效。 语法 utime()方法语法格式如下: os.uti…...
![](https://img-blog.csdnimg.cn/9f5d7dfe5ce340708120b28f4376325d.png)
Redis基础操作以及数据类型
目录 Redis基础操作 java中的i是不是原子操作?不是 数据类型 1. list 2. set 3. Hash哈希 4. Zset有序集合 Redis基础操作 set [key] [value] 设置值 (设置相同的会将原先的覆盖) get [key] 获取值 不能覆盖和替换 ttl [key] 以秒为单…...
![](https://images2017.cnblogs.com/blog/1167150/201801/1167150-20180117232033490-424620393.png)
北京海淀财政局网站/苏州网站seo服务
vmware14 修改vmware默认存放位置 编辑-->首选项 系统安装 界面说明: Install or upgrade an existing system 安装或升级现有的系统 install system with basic video driver 安装过程中采用 基本的显卡驱动 Rescue installed system 进入系统修复模式 Boot fro…...
![](/images/no-images.jpg)
旅游响应式网站建设/百度爱采购推广平台
我目前正在开发一个.NET Core库,我将在另一个项目中用作NuGet包.我已经能够使用项目目录中的“dotnet pack”命令成功打包项目,并将该程序包上传到MyGet.我更喜欢使用“nuget push”命令自动执行推送NuGet包的过程.我的问题是project.json文件中定义的“scripts”属性似乎不在包…...
![](/images/no-images.jpg)
修改数据库密码 进不了网站后台/知乎关键词优化软件
Android NDK( Native Developer Kit )是个工具集,它提供一套方法,使Android应用程序(Java程序)可以内嵌native(C,C)程序。Android应用程序(Java程序)运行于Dalvik虚拟机中。NDK允许应用程序的一部分使用native语言(C,C)来实现。这对很多程序都是有帮助的…...
![](https://img-blog.csdnimg.cn/img_convert/726505ddf1939c417c58f01c2e8c54a5.png)
东莞清洁服务网站建设/关键词优化的作用
首先,关注破千了,感谢大家的支持。D2-Net A Trainable CNN for Joint Description and Detection of Local Featureshttps://arxiv.org/pdf/1905.03561.pdfarxiv.org一、论文出发点传统的关键点检测,例如SI…...
![](/images/no-images.jpg)
昆明网站建设精英/seo网站管理
《计算机网络》作业二第3章计算机网络硬件设备练习一、填空题1《计算机网络》作业二第3章 计算机网络硬件设备练习一、填空题1. 有线传输介质包括________、_________、__________。2. 在局域网中常用的双绞线根据传输特性可以分为_________类。在典型的以太网中,通…...
![](https://images0.cnblogs.com/blog2015/475698/201503/151109043554479.png)
西安网站建设第一品牌/小程序开发流程详细
嗯,昨天将有关JDK的知识稍微整理了一下,现在稍微整理一下有关Tomcat的! 1:Tomcat是什么? Tomcat是当今世界上使用最为广泛的、开源免费的Servlet/JSP容器,其主要功能是用于发布JavaWeb应用。 更多的信息请参…...