SpringBoot统一功能处理

我们要实现以下3个目标:

  1. 统一用户登录权限
  2. 统一数据格式返回
  3. 统一异常处理

1.用户的登录权限校验

1.1Spring AOP用户统一登录验证问题

@Aspect
@Component
public class UserAspect {// 定义切点controller包下、子孙包下所有类的所有方法@Pointcut("execution(* com.example.demo.controller..*.*(..))")public void pointcut(){}//前置方法@Before("pointcut()")public void doBefore() {System.out.println("Before开始执行!");}//环绕方法@Around("pointcut()")public Object doAround(ProceedingJoinPoint joinPoint) {Object obj = null;System.out.println("Around方法开始执行");try {obj=joinPoint.proceed();} catch (Throwable e) {e.printStackTrace();}System.out.println("Around方法执行结束");return obj;}}

在以上Spring AOP的切面中实现用户登录权限校验的功能,有以下几个问题:

  1. 没办法获取到HttpSession对象
  2. 我们要对一部分方法进行拦截,而另一部分方法不拦截,我们是很难定义的。

1.3Spring拦截器

对于以上问题Spring中提供了具体的实现拦截器:HandlerInterceptor,拦截器的实现分为以下连两个步骤:

  1. 创建自定义拦截器:实现HandlerInterceptor接口的preHandle方法(执行具体方法之前预处理)
  2. 自定义拦截器加入WebMvcConfigurer的addInterceptors方法中

1.3.1自定义拦截器

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {HttpSession session = request.getSession(false);if(session != null && session.getAttribute("userinfo") != null) {return true;}response.setStatus(401);return false;}
}

1.3.2将自定义拦截器加入到系统配置

@Configuration
public class AppConfig implements WebMvcConfigurer {//添加拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**") //拦截所有接口.excludePathPatterns("/art/param11"); //排除一些接口}
}
  • addPathPatterns:表示需要拦截的URL,**表示拦截任意方法
  • excludePathPatterns:表示需要排除的URL

说明:以上拦截规则可以拦截此项目中使用的URL,包括静态文件

排除所有的静态资源

@Configuration
public class AppConfig implements WebMvcConfigurer {//添加拦截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**") //拦截所有接口.excludePathPatterns("/art/param11") //排除一些接口.excludePathPatterns("/**/*.js").excludePathPatterns("/**/*.css").excludePathPatterns("/**/*.jpg").excludePathPatterns("login.html").excludePathPatterns("/**/login"); }
}

1.4拦截器实现原理

有了拦截器之后,执行流程如下图所示:

 1.4.1实现源代码分析

所有的Controller执行都会通过一个调度器DispatcherServlet来实现,这一点可以从Spring Boot控制台的打印信息看出来,如下图所示(我们必须触发拦截功能):

 而所有的方法都会执行DispatcherServlet中doDispatch调度方法,doDispatch源码如下:

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {try {ModelAndView mv = null;Object dispatchException = null;try {processedRequest = this.checkMultipart(request);multipartRequestParsed = processedRequest != request;mappedHandler = this.getHandler(processedRequest);if (mappedHandler == null) {this.noHandlerFound(processedRequest, response);return;}HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());String method = request.getMethod();boolean isGet = HttpMethod.GET.matches(method);if (isGet || HttpMethod.HEAD.matches(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {return;}}if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}this.applyDefaultViewName(processedRequest, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);} catch (Exception var20) {dispatchException = var20;} catch (Throwable var21) {dispatchException = new NestedServletException("Handler dispatch failed", var21);}this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);} catch (Exception var22) {this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);} catch (Throwable var23) {this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));}} finally {if (asyncManager.isConcurrentHandlingStarted()) {if (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}} else if (multipartRequestParsed) {this.cleanupMultipart(processedRequest);}}}

我们发现在开始执行Controller之前,会先调用预处理方法applyPreHandle,而这个方法就是获取实现HandlerInterceptor接口的所有所有类,并调用preHandler方法。

2.统一异常处理

统一异常处理使用的是@ControllerAdvice + @ExceptionHandler来实现的,@ControllerAdvice表示控制器通知类,@ExceptionHandler是异常处理器,两个结合表示当出现异常的时候执行某个通知,也就是执行了某个方法事件,具体代码实现如下:

@ControllerAdvice
public class ErrorAdive {@ExceptionHandler(Exception.class) @ResponseBodypublic Object handler(Exception e) {HashMap<String, Object> map = new HashMap<>();map.put("state", 0);map.put("data", null);map.put("msg", e.getMessage());return map;}
}

PS:方法名和返回值可以自定义,重要的是@ControllerAdvice和ExceptionHandler()

我们可以针对不同的异常设置不同的注解,这将返回不同的结果。

@ControllerAdvice
public class ErrorAdive {@ExceptionHandler(Exception.class)@ResponseBodypublic Object handler(Exception e) {HashMap<String, Object> map = new HashMap<>();map.put("state", 0);map.put("data", null);map.put("msg", e.getMessage());return map;}@ExceptionHandler(NullPointerException.class)@ResponseBodypublic Object nullPointerExceptionAdvice(NullPointerException e) {HashMap<String, Object> ret = new HashMap<>();ret.put("state", 0);ret.put("msg", "空指针异常");ret.put("data", null);return ret;}}

当有多个异常通知的时候,匹配顺序为当前类及其子类向上依次匹配。

3.统一数据返回格式

3.1为什么需要统一数据返回格式?

统一数据返回格式有以下优点:

  1. 方便前端程序员更好的接收和解析后端数据接口返回的数据
  2. 降低前端程序员和后端程序员的沟通成本,按照某个格式实现就行了
  3. 有利于项目统一的数据的维护和修改
  4. 有利于后端技术部门的统一规范的标准制定

3.2统一数据返回格式的实现

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

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {/****判断内容是否需要重写,我们这里默认需要重写**/@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);return result;}
}

4.总结

  • 登录校验使用WebMvcConfigurer + HandlerInterceptor实现,
  • 统一异常处理使用@ControllerAdvice + @ExceptionHandler 来实现
  • 统一的返回值处理使用@ControllerAdvice + ResponseBodyAdvice来实现

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

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

相关文章

使用多数据源dynamic-datasource-spring-boot-starter遇到的问题记录

记录使用多数据源dynamic-datasource-spring-boot-starter遇到的问题&#xff1a; 1、工程启动失败 缺少clickhouse连接驱动&#xff0c;引入对应的maven依赖 <!--ck连接驱动--><dependency><groupId>ru.yandex.clickhouse</groupId><artifactId>…

webshell详解

Webshell详解 一、 Webshell 介绍二 、 基础常见webshell案例 一、 Webshell 介绍 概念 webshell就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境&#xff0c;也可以将其称做为一种网页后门。黑客在入侵了一个网站后&#xff0c;通常会将asp或php后门文件与…

国标GB28181安防视频平台EasyGBS大批量通道接入后,创建角色接口未响应的排查

国标GB28181协议视频平台EasyGBS是基于国标GB28181协议的视频云服务平台&#xff0c;支持多路设备同时接入&#xff0c;并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。平台可提供视频监控直播、云端录像、云存储、检索回放、智能告警、语音对讲、平台级…

【并发专题】操作系统模型及三级缓存架构

目录 课程内容一、冯诺依曼计算机模型详解1.计算机五大核心组成部分2.CPU内部结构3.CPU缓存结构4.CPU读取存储器数据过程5.CPU为何要有高速缓存 学习总结 课程内容 一、冯诺依曼计算机模型详解 现代计算机模型是基于-冯诺依曼计算机模型 计算机在运行时&#xff0c;先从内存中…

day20-101. 对称二叉树

101. 对称二叉树 力扣题目链接 给定一个二叉树&#xff0c;检查它是否是镜像对称的。 思路 镜像对称必要的条件就是根节点的左右子树互相对称 左子树的左孩子 右子树的右孩子左子树的右孩子 右子树的左孩子 递归 使用递归前要确定递归的顺序&#xff0c;是前序、后序还…

目标识别数据集互相转换——xml、txt、json数据格式互转

VOC数据格式与YOLO数据格式互转 1.VOC数据格式 VOC&#xff08;Visual Object Classes&#xff09;是一个常用的计算机视觉数据集&#xff0c;它主要用于对象检测、分类和分割任务。VOC的标注格式&#xff0c;也被许多其他的数据集采用&#xff0c;因此理解这个数据格式是很重…

QT--day4(定时器事件、鼠标事件、键盘事件、绘制事件、实现画板、QT实现TCP服务器)

QT实现tcpf服务器代码&#xff1a;&#xff08;源文件&#xff09; #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//给服务器指针实例化空间server new QTc…

【图论】强连通分量进阶

一.作用 强连通分量可以判断环和进行缩点。还有一系列作用.... 这篇文章介绍缩点 二.题目 https://www.luogu.com.cn/problem/P2341 三.思路 我们分析可以知道当一个点没有出度时&#xff0c;则为最受欢迎的牛。但如果有多个出度&#xff0c;则没有最受欢迎的牛。 这是只有…

用户权限管理是保证企业图文档安全最有效的策略

企业拥有大量的图文档数据&#xff0c;涉及多个部门和员工&#xff0c;因此需要建立有效的用户权限管理策略&#xff0c;以保护图文档的安全。智橙平台将在线图文档管理与BOM系统的融合应用为企业提供了强大的权限管理功能&#xff0c;能够确保只有授权用户能够访问和编辑特定的…

Linux运维面试题(三)之数据库管理

Linux运维面试题&#xff08;三&#xff09;之数据库管理 1. SQL语句2.集群主从服务器原理主从故障切换单台Mysql达到性能瓶颈时&#xff0c;如何处理 3.索引&#xff08;软优化&#xff09;什么是索引索引的分类劣势&#xff08;优点&#xff1a;效率和减少数据表内排序和随机…

java实现5种不同的验证码图片,包括中文、算式等,并返回前端

导入以下依赖 <!--图片验证码--><dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version></dependency> 编写controller package com.anXin.user.controlle…

【vue】 Tinymce 富文本编辑器 不想让上传的图片转换成base64,而是链接

前言&#xff1a;最近项目上需要使用富文本编辑器&#xff0c;觉得tinymce很不错就用了&#xff0c;具体怎么在项目中使用参考 【vue】 vue2 中使用 Tinymce 富文本编辑器 【vue】 Tinymce 数据 回显问题 | 第一次正常回显后面&#xff0c;显示空白bug不能编辑 这两天又遇到了…

Open3D(C++) 根据索引提取点云

目录 一、功能概述1、主要函数2、源码二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。爬虫网站自重,把自己当个人 一、功能概述 1、主要函数 std::shared_ptr<PointCloud> SelectByIn

如何运行疑难解答程序来查找和修复Windows 10中的常见问题

如果Windows 10中出现问题&#xff0c;运行疑难解答可能会有所帮助。疑难解答人员可以为你找到并解决许多常见问题。 一、在控制面板中运行疑难解答 1、打开控制面板&#xff08;图标视图&#xff09;&#xff0c;然后单击“疑难解答”图标。 2、单击“疑难解答”中左上角的…

2023华数杯数学建模竞赛C题思路解析

如下为&#xff1a;2023华数杯数学建模竞赛C题 母亲身心健康对婴儿成长的影响 的思路解析 C题 母亲身心健康对婴儿成长的影响 母亲是婴儿生命中最重要的人之一&#xff0c;她不仅为婴儿提供营养物质和身体保护&#xff0c;还为婴儿提供情感支持和安全感。母亲心理健康状态的不…

O3DE的Pass

Pass介绍 Pass是具有输入和输出的渲染过程。 在最终渲染帧中看到的每个细节都是通过一系列Pass&#xff08;前一个Pass的输出是下一个Pass的输入&#xff09;计算出来的。Pass可以生成图像&#xff08;作为纹理、缓冲区或渲染目标&#xff09;。每个图像都包含关于场景的特定…

CTFSHOW php 特性

web89 数组绕过正则 include("flag.php"); highlight_file(__FILE__);if(isset($_GET[num])){$num $_GET[num]; get numif(preg_match("/[0-9]/", $num)){ 是数字 就输出 nodie("no no no!");}if(intval($num)){ 如果是存在整数 输出 flagecho …

Qt tabwidget中插入widget

一、简单介绍 QT->tabWidget&#xff1a;标签页面。 在ui中通过工具栏自定义拉取控件&#xff0c;其中tabwidget可以可以创建多个标签页面&#xff0c;默认生成两个tab_widget(tab_1/tab_2)。并且可以在ui中右键自由添加控制删除等标签页&#xff0c;切换标签页就是切换widg…

uniapp点击图片放大预览

阐述 有些时候我们在用uniapp显示图片时&#xff0c;有的不宜全部显示到屏幕上&#xff0c;uniapp提供了一个非常好用的api。 实现方式如下&#xff1a; <template><view class"content"><image class"logo" src"/static/images/a.…

SOC FPGA之流水灯设计

一、DS-5简介 Altera Soc EDS开发套件的核心是Altera版ARM Development Studio 5(DS-5)工具包&#xff0c;为SoC器件提供了完整的嵌入式开发环境、FPGA自适应调试和对Altera工具的兼容。 1.1 DS-5 eclipse破解 首先下载破解器 然后进入cmd运行&#xff0c;进入到破解器所在文…