浅谈 Spring AOP框架 (2)——Spring统一功能处理

news2024/9/28 14:35:53

文章目录

  • 一、AOP实战——SpringBoot统一功能处理
    • 1.1、使用拦截器实现用户登录权限的统一验证
      • 1.1.1、使用原生Spring AOP实现统一拦截的难点
      • 1.1.2、Spring 拦截器
        • 1.1.2.1、Spring拦截器 使用步骤
        • 1.1.2.2、拦截器实现原理
    • 1.2、统一数据格式返回
      • 1.2.1、为什么要返回统一的数据格式
      • 1.2.2、返回统一数据格式的步骤
        • 1.2.2.1、创建一个类,并在类上添加注解@ControllerAdvice
        • 1.2.2.2、且该类要实现接口ResponseBodyAdvice,并重写supports、beforeBodyWrite方法(统一对象是在此方法中实现的)
        • 1.2.3、最终版统一数据格式返回
    • 1.3、统一异常处理
      • 1.3.1、感知系统异常
      • 1.3.2、统一返回异常对象。

一、AOP实战——SpringBoot统一功能处理

1.1、使用拦截器实现用户登录权限的统一验证

以前进行用户登陆权限的验证方法:

@RestController
@Reques tMapping("/user")
public class UserController {
/**
*某方法1
*/
@RequestMapping("/m1")
public object method (HttpServletRequest request) {
	  //有session 就获取,没有不会创建
	  HttpSession session = request. getSession(false);
	  if (session != null && session.getAttribute ("userinfo") != null) {
	  //说明已经登录,业务处理
	  return true;
	} else {
	//未登录
	  return false;
	  }
}
/**
*某方法2
*/
@RequestMapping ("/m2")
public object method2(HttpServletRequest request) {
  //有session 就获取,没有不会创建
  HttpSession session = request.getSession(false);
  if (session != null && sess ion.getAttribute("userinfo") != null) {
  //说明已经登录,业务处理
  return true;
} else {
//未登录
  return false;
  }
}
// 其他方法...

1.1.1、使用原生Spring AOP实现统一拦截的难点

前面已经学习了AOP知识知道可以通过AOP规则拦截未登录页面(除了拦截接口,还有前端页面…),但是使用原生的Spring AOP实现同意拦截有一些难点:
(1)、切点的拦截表达式规则复杂,难以定义
(2)、在切面类里拿到 HttpSession类 比较难

1.1.2、Spring 拦截器

Spring 引入 拦截器 解决Spring AOP上述所说的这些问题。

1.1.2.1、Spring拦截器 使用步骤

(1)、自定义一个拦截器类(随意命名),该类必须实现 HandlerInterceptor,并且该自定义类里必须重写preHandle()方法。
在这里插入图片描述
(2)、将⾃定义拦截器加⼊到系统配置
再自定义一个配置类(命名随意),此配置类必须实现 WebMvcConfigurer ,并且当前这个配置类是需要随着Spring的启动而启动,因此配置类必须加上注解@Configuration,然后配置类里必须重写addInterceptors()方法,然后将上面自定义的拦截类加入到该配置类中,此时我们自定义的拦截类才能生效。
在这里插入图片描述

早期的项目数据交互流程:
在这里插入图片描述

拦截器出现之后:
在这里插入图片描述

1.1.2.2、拦截器实现原理

那为什么拦截器可以在controller执行之前先执行??

所有的Controller执行时都会通过一个调度器 DispatcherServlet 来实现:
在这里插入图片描述
而程序中所有方法都会执行 DispatcherServlet 中的 doDispatch() 调度方法,doDispatch()源码中在开始执行 Controller 之前,首先是调用了预处理方法 applyPreHandle(),而applyPreHandle的源码中,首先是获取到所有的拦截器HandlerInterceptor,并执行拦截器中的preHandle()方法,因此拦截器的预处理会比Controller先执行。

如果大家感兴趣 doDispatch() 、applyPreHandle的源码的话,可以自己去搜索看看,由于篇幅太长,我就不放在这里了。

1.2、统一数据格式返回

1.2.1、为什么要返回统一的数据格式

统一数据返回格式的优点有很多,如下:
(1)、方便前端程序员更好的接收和解析后端接口返回的数据。
(2)、降低前端程序员和后端程序员的沟通成本,按照某个格式实现就行了,因为所有接口都是这样返回的。
(3)、有利于项目统一数据的维护和修改
(4)、有利于后端技术部门统一规范的标准制定, 不会出现稀奇古怪的返回内容。

1.2.2、返回统一数据格式的步骤

1.2.2.1、创建一个类,并在类上添加注解@ControllerAdvice

在这里插入图片描述

1.2.2.2、且该类要实现接口ResponseBodyAdvice,并重写supports、beforeBodyWrite方法(统一对象是在此方法中实现的)

例子:
在这里插入图片描述

num接口下前端接收到的数据格式:
test接口下前端接收到的数据格式:
在这里插入图片描述

当程序中设置了统一的数据返回格式后:
在这里插入图片描述

注意一个知识点
在这里插入图片描述
那为什么会出现这个异常信息呢?其实是因为:只要你的返回类型不是String,都能被统一数据返回格式转成标准的json格式返回给前端。String和其他类型都不一样:
在这里插入图片描述
所以我们在统一返回时,对于String,不能再借助Spring把HashMap转成json字符串格式了,需要对String进行单独的处理:先判断当前body是否为String,如果是,使用jackson将HashMap手动转为json字符串才行。
在这里插入图片描述
在这里插入图片描述
但是其实我们的统一数据返回格式还有其他问题:
在这里插入图片描述

1.2.3、最终版统一数据格式返回

待补充。

1.3、统一异常处理

1.3.1、感知系统异常

如何感知到异常??使用注解:@ControllerAdvice 感知到异常:即自己定义的异常类上加上该注解,加上该注解之后,当前类会随着项目的启动而启动。注解@ControllerAdvice表示控制器通知类。

然后该自定义的异常类里的方法需要加上注解 @ExceptionHandler(异常管理器),加上这个注解之后,相当于订阅了系统的异常事件了。如果项目出了异常,加了该注解的方法就能够获取到项目的异常。 @ExceptionHandler(这里面写的是什么异常的反射,就能拿到什么异常),比如说:@ExceptionHandler(Exception.class) 那就能拿到所有异常,如果是:@ExceptionHandler(IOException.class) 就能拿到IO产生的异常…

在这里插入图片描述
但其实虽然我们定义了统一处理的异常类,上述图片我们定义了空指针异常统一处理、算数异常统一处理,但是其实如果程序代码中若还出现了其他异常如:越界异常、栈溢出异常…这些异常我们还是没办法统一处理到,这该怎么办?要么继续添加定义该异常的统一异常处理方法,要么定义一个保底的异常方法。比较推荐第二种办法。
在这里插入图片描述

1.3.2、统一返回异常对象。

感知到异常之后,再将异常封装成统一对象返回给前端。

上述项目例子链接(待补充)

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

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

相关文章

Linux/C 高级——条件编译

1.根据宏是否定义 #define 宏名 #ifdef 宏名 /*code1*/ #else /*code2*/ #endif 执行顺序:宏名如果定义则编译code1,否则编译code2 例子: 2.根据宏值 #define 宏名 值 #if 宏名 /*code1*/ #else /*code2*/ #endif 执行顺序:宏的值…

真值表编程

打开真值表进行编辑 在图表中创建并标记真值表后,您可以指定其逻辑行为。要打开真值表,请双击真值表函数。 默认情况下,真值表包含一个条件表和一个动作表,每个表都有一行。条件表包含一个决策列D1和一个动作行。 选择动作语言 …

达梦数据库 数据类型

达梦数据类型 1.背景2.要求3.描述与使用3.1 常规数据类型3.1.1 字符数据类型3.1.1.1 CHAR类型3.1.1.2 CHARACTER类型3.1.1.3 VARCHAR类型 3.1.2 数值数据类型3.1.2.1 NUMERIC类型3.1.2.2 DECIMAL类型3.1.2.3 DEC类型3.1.2.4 NUMBER类型3.1.2.5 INTEGER类型3.1.2.6 INT类型3.1.2…

VC++_opencv插件ImageWatch的安装和使用

1、插件安装 以VS2015为例: 进入扩展和更新界面,点“联机”,然后输入“ImageWatch”进行搜索: 2、安装完毕后重启VisualStudio 如下图在菜单“视图\其他窗口”找到“ImageWatch”这个栏目 然后点开: 也可让其停靠在Vi…

c++----初识模板

大家好,这篇博客想与大家分享一些我们c中比较好用的知识点。模板。首先咧,我们都知道模板嘛,就是以前人的经验总结出来的知识。方便我们使用。这里的模板也是一样的。当我们学习过后,对于一些在c中的自定义函数,我们在…

QList 的访问方式list.at(index) 和 list[index] 对比

QList 是 Qt 框架中提供的一个模板容器类,用于存储和操作一系列元素。它提供了两种不同的方式来访问容器中的元素:.at()成员函数和下标运算符 []。以下是这两种方式的区别: 1. QList::at() 方法 at()是一个成员函数,它允许通过索…

04--Docker

前言:前面写过关于DockerKubernetes的部署,主要是针对国产化linux系统的适配问题,并没有对docker进行复习。这里整理一下docker的知识点,用作容器化微服务的起点,主要为日常工作配置使用,本章可能有点长&am…

详解Xilinx FPGA高速串行收发器GTX/GTP(4)--TX/RX接口的数据位宽和时钟设计

目录 1、时钟设计 2、TX接口 3、接口位宽与时钟的关系 4、时钟来源方案 5、TX端内部的时钟分频设计 6、RX接口 文章总目录点这里:《FPGA接口与协议》专栏的说明与导航 1、时钟设计 GT收发器内部比较复杂,所使用的时钟就不止一个,比较主要的时钟有两个,架构…

做好网络安全风险管理必备的5种能力

网络安全风险管理和网络安全防护是两个密切相关但不可互换的概念,网络安全防护侧重于应对攻击和响应正在发生的安全事件,而网络安全风险管理则强调从更全面的视角去评估企业的安全状况和面临的威胁态势,包括了从对组织运营、商誉、财务和合规…

值得注意!家里有带毛发动物就有浮毛?宠物空气净化器一键净化

上次跟朋友逛完街去她家,她家热情的哈基米开门就一个猛冲,我朋友接住就是一顿猛亲,亲猫一时爽,汗液粘着猫毛,粘得满手臂、满脸都是,看得鼻炎星人头皮发麻...好多养宠物的都说,梳毛根本不管用&am…

关于let 、const和Object.freeze的使用记录

let和const的使用差异 let对象变量,可以修改对象属性,可以给变量重新赋值 const对象变量,可以修改对象属性,不可以给变量重新赋值 Object.freeze()返回一个不可变对象,需要接收返回值。不会改变原参数的性质

LVS详解及其NAT模式与DR模式部署(全网最详细!!!)

文章目录 LVS集群概念集群和分布式 LVS运行原理LVS简介LVS专业术语工作原理LVS调度算法ipvsadm常用命令 LVS工作模式及其原理NAT模式DR模式TUN模式fullnet模式 部署NAT模式集群案例DR模式(企业中最常用)LVS持久链接(session回话问题解决&…

SimpleITK C++版在windows 下编译

一般都是用python 版的SimpleITK,因为项目需要集成到C Qt上,然后ITK用起来又不如SimpleITK方便,所有就编译了C版的Sitk,下面记录下过程。 版本对应 SimpleITK 编译需要ITK ,而且不同版本需要对应不同的ITK,sitk 2.2.1 对应ITK 5…

基于Hadoop的海量电商用户行为分析及机器学习购买预测研究【购物行为分析、100万条数据案例项目】

文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主引言研究背景国内外研究现状研究目的研究意义 关键技术理论介绍Hadoop集群搭建及数据准备Hadoop全套组件搭建数据集介绍数据预处理 基于大数据的电商用户行为指标分析HIve准备数据表flume配…

在哪些行业中,3D 技术发挥了重要作用?

3D技术目前常见于行业或领域中的应用,主要包括3D数字孪生、3D打印等。3D数字孪生技术作为一种前沿技术,在多个行业中发挥着重要作用,它通过创建物理实体的数字化副本,实现对实体的实时监控、预测和优化。以下是一些3D数字孪生技术…

【总结】TCP/IP四层模型的理解

在开始之前放上一张本文章的核心图片,要一直记住图中的内容!!! 一、概念理解 首先我们知道分析网络的时候有两种模型,一种是OSI七层模型,另一种就是TCP/IP四层模型。一般来说,我们常用的就是TC…

医疗工厂网络同步时钟,子母钟系统结构,可使用十年以上

在医疗和工业领域,准确的时间信息对于确保各项工作的高效运行至关重要。网络同步时钟系统因其高精度、易维护等特点,成为现代医疗工厂不可或缺的时间管理工具。本文将详细介绍网络同步时钟系统的优点及其技术细节。 一、网络同步时钟优点 网络同步时钟系…

工业设计用什么CAD软件?SolidWorks 成为您创意实现的得力助手

随着科技的发展,工业设计已经进入了数字化时代。对于设计师来说,选择一款高效、功能全面的设计软件至关重要。在市场上众多的CAD(计算机辅助设计)软件中,SolidWorks因其出色的性能和广泛的适用性而备受青睐。本文将介绍…

各地区搭子群扩列群h5公众号小程序app开源版开发

各地区搭子群扩列群多开h5公众号小程序app开源版开发 多端应用,源码开源支持自主二开;域名授权。 搭子群和扩列群通常是用来帮助人们找到志同道合的朋友或活动伙伴的社交平台。这些平台可以采用H5页面、微信公众号、小程序或独立的应用程序等形式。下面…

winform 设置TabControl中tab标签的宽度

问题: tabpage标签太挤了,标签间的间隔也不明显。解决方法: 将TabControl的SizeMode属性设为Fixed设置ItemSize的大小(width) 调整后效果: