Spring Boot 系列4 -- 统一功能处理

目录

前言

1. Spring AOP 用户统⼀登录验证的问题

1.1 自定义拦截器

1.2 配置拦截器并配置拦截的规则

1.3 拦截器的原理源码分析

2. 统一异常处理

2.1 实现统一异常处理

2.2 测试统一异常处理

3. 统一的数据格式返回

3.1 统⼀数据返回格式的实现

3.2 测试统一的数据返回


前言

        Spring AOP是一个面向切面编程的框架,可以同设置要做处理的类为切面,设置切点进行设置拦截规则,然后定义通知,实现一定的拦截规则.但是我们原生的Spring AOP的框架使用起来比较繁琐.为了解决如此之类的Spring AOP的问题.对于Spring AOP的实战,本文将介绍三种功能.

1. 统一用户登录权限验证

2. 统一数据返回格式

3. 统一异常处理

1. Spring AOP 用户统⼀登录验证的问题

假设我们要实现这样一个功能,在多个页面进行判断用户的登录状态,然后发现当前用户的登录状态为空的时候进行跳转到登录页.

        我们之前的做法是,在每个页面的路由中进行判断用户的登录状态,显然这些操作是重复的,后来我们又学习了Spring AOP,我们试想可以将需要进行验证的类进行设置为切面,在需要地方进行配置拦截的规则,然后进行设置前置通知.这个思想是可以的,但是我们实现起来会遇到两个问题.

1.  没办法获取到 HttpSession 对象(我们需要对Session进行判断当前的用户登录状态)

2.  我们要对⼀部分方法进行拦截,而另⼀部分方法不拦截,如注册⽅法和登录方法是不拦截的,这样的话排除⽅法的规则很难定义,甚至没办法定义。

针对一以上的问题,Spring 框架为我们提供了一个具体实现的拦截器:HandlerInterceptor

而我们要使用这个拦截器实现自己的功能,可以具体分为两步:

 下面我们使用代码进行实现上述的功能:

1.1 自定义拦截器

具体代码:

public class LoginInterceptor implements HandlerInterceptor {/*** 此方法返回一个boolean类型的值,返回true表示验证成功,继续执行后续流程*///  重写preHandle方法实现自己的业务代码@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 用户登录登录业务判断HttpSession session = request.getSession(false);if (session != null && session.getAttribute("userinfo") != null){// 用户已经登录return true;}// 没有登录,可以进行跳转到登录页面,或者返回一个401 或者403 没有权限码response.sendRedirect("/login1.html");
//        response.setStatus(403);// 上面两者取一个即可return false;}}

1.2 配置拦截器并配置拦截的规则

红色部分就是将自定义的拦截器添加到项目中,然后绿色是一个扩展,就是在路由前面加前缀.

 具体代码:

package com.example.demo.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** Created with IntelliJ IDEA.* Description:将自定义拦截器加入到WebMvcConfigurer中,重写addInterceptors方法进行设置拦截规则* User: YAO* Date: 2023-07-14* Time: 15:04*/
@Configuration
public class AppConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**")  // 拦截规则设置,此处进行拦截所有请求.excludePathPatterns("/user/login").excludePathPatterns("/user/reg").excludePathPatterns("/user/get-num").excludePathPatterns("/user/get-string").excludePathPatterns("/img/**").excludePathPatterns("/**/*.html");}// 所有的接⼝添加 api 前缀// 给路由进行添加前缀 ,设置为 true 表示启动前缀
//    @Override
//    public void configurePathMatch(PathMatchConfigurer configurer) {
//        configurer.addPathPrefix("api", c -> true);
//    }
}

我们对上述实现的拦截器进行验证

 当进行点击的时候,因为没有Session所以直接跳转到我们设置的登录页面了.

可以看出没有进行设置过Cookie的,就是没有Session连接. 

1.3 拦截器的原理源码分析

所有的方法都会执行 DispatcherServlet 中的 doDispatch 调度方法,观察源码发现:

  点击这个applyPreHandle,applyPreHandle 中会获取所有拦截器 HandlerInterceptor 并执行拦截器中的 preHandle 方法,这与之前我们实现拦截器的步骤对应.

2. 统一异常处理

        统一异常处理是指 在应用程序中定义一个公共的异常处理机制,用来处理所有的异常情况。 这样可以避免在应用程序中分散地处理异常,降低代码的复杂度和重复度,提高代码的可维护性和可扩展性.\

        统⼀异常处理使⽤的是 @ControllerAdvice + @ExceptionHandler 来实现的,@ControllerAdvice 表示控制器通知类,@ExceptionHandler 是异常处理器,两个结合表示当出现异常的时候执行某个通知,也就是执行某个方法事件.

2.1 实现统一异常处理

2.2 测试统一异常处理

我们自己创建一个路由,其中内容出现一个空指针异常,我们查看是否能进行返回给前端处理. 

我们设置的异常处理起到作用了.那么如果不设置,异常的处理,会出现什么样的现象?

就会直接将控制台打印的异常返回给前端,前端拿到数据就很懵.所以统一的异常处理还是很有必要的.

3. 统一的数据格式返回

3.1 统⼀数据返回格式的实现

下述是我们一般的统一返回的数据的格式

实现统一的数据返回格式可以使用 @ControllerAdvice + ResponseBodyAdvice 的方式实现,具体步骤如下:

  1. 创建一个类,并添加 @ControllerAdvice 注解;
  2. 实现 ResponseBodyAdvice 接口,并重写 supports 和 beforeBodyWrite 方法.

 上述部分就是记性统一的数据格式返回.

其中需要注意的是,当返回的类型为String类型的时候,我们需要使用Jackson将String转换成json再进行返回.也就是绿色的部分.

package com.example.demo.config;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
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.servlet.mvc.method.annotation.ResponseBodyAdvice;import java.util.HashMap;/*** Created with IntelliJ IDEA.* Description:* User: YAO* Date: 2023-07-14* Time: 17:25*/
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {HashMap<String, Object> result = new HashMap<>();result.put("state",1);result.put("msg", "");result.put("data", body);if (body instanceof String){// 需要特殊进行处理,因为String比较特殊,既不是基础类型也不是对象,进行重写的时候String用的格式化工具是自己独有的// 在body返回之前没有加载好.需要将String进行单独进行处理.使用Jackson将String转换成json再进行返回.try {return objectMapper.writeValueAsString(result);} catch (JsonProcessingException e) {e.printStackTrace();}}return result;}
}

3.2 测试统一的数据返回

可以看出返回的格式是我们规定好的格式.这就变得更加统一.


 好啦本文就总结到这了,点个赞吧,谢谢!!!

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

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

相关文章

QT 使用单例模式

目录 1. 单例模式介绍 2.单例模式实现 1. 单例模式介绍 有些时候我们在做 qt 项目的时候,要用到很多类. 例如我们用到的类有 A,B,C,D. 其中,A 是 B,C,D 中都需要用到的类,A 类非常的抢手. 但是,A 类非常的占内存,定义一个 A 对象需要 500M 内存,假如在 B,C,D 中都定义一个 A 类…

浏览器不同源的页面之间如何跨域通信

目录 1&#xff0c;需求2&#xff0c;难点3&#xff0c;思路浏览器不同源的页面之间如何跨域通信&#xff1f; 4&#xff0c;实现第1版第2版最终版其他的问题1&#xff0c;页面路径需完全一致。2&#xff0c;事件注册问题 1&#xff0c;需求 现在有2个项目&#xff0c;页面路径…

Xilinx A7开发板LVDS IO无输出问题解决方法

使用A7-35T FGG484的FPGA开发板bank16上的IO作为差分LVDS的输入输出&#xff0c;搭建输入输出测试工程发现LVDS可以输入、无法输出。查阅UG471&#xff0c;找到如下信息&#xff1a; 手册中已经针对A7的LVDS做了明确的应用说明&#xff1a; &#xff08;1&#xff09;HP bank上…

数组的学习

数组学习 文章目录 数组来由数组的使用数组的内存图变量声明和args参数说明声明分配空间值的省略写法数组的length属性数列输出求和判断购物金额结算Arrays的sort和toString方法Arrays的equals和fill和copyOf和binarySearch方法字符数组顺序和逆序输出 数组来由 录入30个学生…

telnet检验网络能不能通

telnet检测网络能不能通&#xff08;ip地址端口号&#xff09;

阿里云平台WoSignSSL证书应用案例

沃通CA与阿里云达成合作并在阿里云平台上线WoSign品牌SSL证书。自上线以来&#xff0c;WoSignSSL证书成为阿里云“数字证书管理服务”热销证书产品&#xff0c;获得阿里云平台客户认可&#xff0c;助力阿里云平台政府、金融、教育、供应链、游戏等各类行业客户实现网站系统数据…

利用OpenCV实现图像拼接

一、介绍 图像拼接. 二、分步实现 要实现图像拼接&#xff0c;简单来说有以下几步&#xff1a; 对每幅图进行特征点提取对对特征点进行匹配进行图像配准把图像拷贝到另一幅图像的特定位置对重叠边界进行特殊处理 PS&#xff1a;需要使用低版本的opencv&#xff0c;否则无法使…

扩散模型实战(二):扩散模型的发展

推荐阅读列表&#xff1a; 扩散模型实战&#xff08;一&#xff09;&#xff1a;基本原理介绍 扩散模型从最初的简单图像生成模型&#xff0c;逐步发展到替代原有的图像生成模型&#xff0c;直到如今开启 AI 作画的时代&#xff0c;发展速度可谓惊人。下面介绍一下2D图像生成相…

Unity Image(RawImage) 实现按轴心放大缩小,序列化存储轴心信息,实现编译器窗口保存轴心

工作时分配给我的要实现的功能&#xff0c;写的时候遇到挺多的坑的&#xff0c;在此记录一下 效果 放大缩小的效果 2.编译器扩展窗口记录 实现点 1.Json序列化存储图片轴心位置, 放大倍率&#xff0c;放大所需要的事件 2.用了编译器扩展工具便于保存轴心信息坑点 1.Imag…

FANUC机器人SRVO-300机械手断裂故障报警原因分析及处理办法

FANUC机器人SRVO-300机械手断裂故障报警原因分析及处理办法 首先,我们查看报警说明书上的介绍: 总结:即在机械手断裂设置为无效时,机器人检测出了机械手断裂信号(不该有的信号,现在检测到了,所以报警) 使机械手断裂设定为无效/有效的具体方法:  按下示教器的MENU菜单…

弘扬“两弹一星”精神,勇攀科学技术高峰——道本科技商业大学党日活动圆满落幕

2023年8月2日&#xff0c;道本科技与商业大学携手举办了一场主题为“弘扬‘两弹一星’精神&#xff0c;勇攀科学技术高峰”的党日活动。本次活动旨在了解党领导下的中国核工业发展历程&#xff0c;传承和弘扬“两弹一星”精神&#xff0c;同时展示道本科技创新产品&#xff0c;…

智慧工地云平台源码,基于微服务+Java+Spring Cloud +UniApp +MySql开发

智慧工地可视化系统利用物联网、人工智能、云计算、大数据、移动互联网等新一代信息技术&#xff0c;通过工地中台、三维建模服务、视频AI分析服务等技术支撑&#xff0c;实现智慧工地高精度动态仿真&#xff0c;趋势分析、预测、模拟&#xff0c;建设智能化、标准化的智慧工地…