Spring统一功能

文章目录

  • 一、什么是统一功能
  • 二、拦截器
    • 2.1 什么是拦截器
    • 2.2 拦截器的使用
    • 2.3 案例:不拦截前端的请求
    • 2.4 拦截器是如何实现的 ---- >分析DispatcherServlet源码分析
  • 三、适配器模式
  • 四、统一数据返回格式
  • 五、统一异常
  • 六、案例:在图书管理系统使用统一功能

一、什么是统一功能

  1. 什么是统一功能:大家都要做的事情,每一个接口都要执行这个操作
  2. 统一功能包含两个部分
    • (1)Spring本身提供的统一功能
    • (2)Spring本身并没有提供某个统一功能,但我们又需要,如何去自定义

二、拦截器

2.1 什么是拦截器

  1. 什么是拦截器:主要用来拦截用户的请求,在指定方法前后,根据业务需要执行预先设定的代码。
    • 统一功能之一:是Spring提供的统一功能的其中之一,可以公共地对一个信息进行处理
    • 作用维度:拦截器的作用维度是URL,像Service代码没有配置我们是拦截不了的
  2. 使用拦截器后的执行流程
    • 请求:之前请求过来,先进入Controller,如果有拦截器,是先进入拦截器看有没有需要预先执行的方法,如果有且拦截器放行了,才会去执行Controller里的代码
    • 响应:返回时,当Controller里的方法全部执行完,会被拦截器拦截,执行拦截器中设置的【响应后的代码】
      在这里插入图片描述

2.2 拦截器的使用

在这里插入图片描述

@Configuration
public class webConfig implements WebMvcConfigurer { //WebMvcConfigurer是一个Mvc的配置器@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor)  //添加拦截器.addPathPatterns("/**")	   //要拦截哪些方法.excludePathPatterns("");  //哪些不进行拦截}
}
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("目标方法执行前");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("目标方法执行后");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}
  1. 关于路径的定义:addPathPatterns 和 excludePathPatterns里放的是网络路径,而非文件路径
    • /*:一级路径
      • 能匹配/user、/book
      • 不能匹配/user/login
    • /**:任意级路径
      • 能匹配/user、/user/login、/book/addBook,所有路径都能匹配
    • /book/*:/book下的一级路径
      • 能匹配/book/addBook
      • 不能匹配/book/addBook/1,/book
    • /book/**:/book下的任意级路径
      • 能匹配/book、/book/addBook
      • 不能匹配/user/login

2.3 案例:不拦截前端的请求

  1. 问题描述
    • 因为此时除了【/user/login】这个后端请求,所有的请求都被拦截了,这包括了前端的所有请求(甚至图片的访问都被拦截了)
    • 比如我们无法通过在浏览器输入【http://127.0.0.1:8080/login.html】来访问这个网页并进行后续的登录操作
@Configuration
public class webConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/user/login");}
}
  1. 解决方法:把前端的访问路径通过【excludePathPatterns()】排除掉
    在这里插入图片描述
    在这里插入图片描述
  2. 关于excludePathPatterns()的其他写法
    在这里插入图片描述

2.4 拦截器是如何实现的 ---- >分析DispatcherServlet源码分析

  1. 源码如何阅读:找核心代码,不要钻牛角尖。一行一行地细细研究,很快就会忘记当前在哪了。
    • 阅读方法:切忌从头到尾一行一行地去读代码,一点一点去研究,一定要找到关键代码后,在宏观上对整个流程或整个原理有一个认识后,有时间再去看里面的细节
    • 快捷键:如果我们看调用代码时,忘记了前后调用的顺序,可以通过下面两个快捷键来操作
      • ctrl + [:回到上一步操作
      • ctrl + ]:来到下一步操作
  2. 步骤
    • 程序启动后,拦截器会初始化DispatcherServlet
      在这里插入图片描述
      在这里插入图片描述

    • DispatcherServlet的 init 阶段
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    • DispatcherServlet的 service 阶段
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    • DispatcherServlet的 destory 阶段

三、适配器模式

  1. 什么是适配器模式
    在这里插入图片描述
    在这里插入图片描述

  2. 适配器模式的实现

    • 此处我们模拟Slf4j:@Slif4j既是一个典型的模型模式,也是一个适配器模式
      • 一个框架用到的模式是非常多的,可能源码的短短几行代码就能体现出2,3种设计模式
    • 代码
      • 为什么用户不能直接调log4j和slf4j:不能保证所有的人都用所有的日志框架,项目之间可能会有冲突,需要有一个门面
        在这里插入图片描述
  3. 应用场景:版本升级

    • 适配器模式是一种补偿模式,不是一开始就有的,是后期设计上的缺陷没办法修改了的打补丁式的无奈之举
    • 所以适配器的应用场景主要是对正在运行的代码进行改造,并且希望复用原有代码实现新的功能,比如版本升级等

四、统一数据返回格式

  1. 效果:使每一个接口返回的数据都是同种格式的

  2. 实现方法:使用@ControllerAdvice注解 + ResponseBodyAdvice接口 + 重写两个方法
    在这里插入图片描述

  3. 当前代码存在的问题
    在这里插入图片描述
    在这里插入图片描述

  4. 为什么返回结果为String时,后端无法正确执行
    在这里插入图片描述
    在这里插入图片描述

  5. 上述问题的解决方法
    在这里插入图片描述

  6. 为什么用了ObjectMapper后,可以解决String的问题
    在这里插入图片描述

  7. 统一数据返回格式的优点

    • 由于返回的数据都变成了Result,方便前后端沟通,前端人员知道返回的数据是什么样的
    • 后端代码不需要太多的改动,就可以统一返回格式

五、统一异常

  1. 为什么要有统一异常:自己的错误自己知道即可,不给外界知道

    • 对于后端而言:我们不希望把一些诸如空指针的错误放给前端看
    • 对于前端而言:也希望不给用户看太细致的错误,而是统一跳转到一个页面,比如内部出错了,找不到页面之类的
  2. 什么时候统一异常不会生效:如果代码已经手动用try-catch捕获了,就不会被我们写的【统一异常处理】捕获到了,如果没有手动捕获,才会被统一处理

  3. 针对的对象:主要针对的是运行时异常

  4. 代码

    • 固定的三个注解:@ResponseBody、@ControllerAdvice、@ExceptionHandler
    • @Slf4j:建议加上日志,方便后续找错
      在这里插入图片描述
  5. @ControllerAdvice注解分析
    在这里插入图片描述

  6. 为什么统一异常代码能生效
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  7. 如何阅读源码:注意源码的版本匹配

    • 方式一:IDEA上点击Download Source
    • 方式二: 去Spring的github上查看

六、案例:在图书管理系统使用统一功能

  1. 登录:登录没有进行拦截,所以没有连接失败的情况(不需要写error),只需要更改前端代码即可
    在这里插入图片描述
  2. 返回图书列表
    在这里插入图片描述
  3. 添加图书
    在这里插入图片描述

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

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

相关文章

【Linux】锁|死锁|生产者消费者模型

🔥博客主页: 我要成为C领域大神🎥系列专栏:【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ ​ 访问互斥 …

ChatGPT在程序开发中的应用:提升生产力的秘密武器

在当今飞速发展的科技时代,程序开发已经成为许多企业和个人必不可少的技能。然而,编写代码并非总是顺风顺水,面对复杂的算法、繁琐的调试、持续不断的需求变更,程序员们常常感到压力山大。在这种情况下,ChatGPT应运而生…

ArkTS开发系列之Web组件的学习(2.9)

上篇回顾:ArkTS开发系列之事件(2.8.2手势事件) 本篇内容: ArkTS开发系列之Web组件的学习(2.9) 一、知识储备 Web组件就是用来展示网页的一个组件。具有页面加载、页面交互以及页面调试功能 1. 加载网络…

深度学习(理论知识)

一、监督学习、自监督和半监督 1、监督学习(Supervised Learning) 概念 监督学习是一种机器学习方法,通过使用带标签的数据进行训练,模型学习从输入到输出的映射关系。数据集中的每个样本都包含输入特征(features&am…

【前端】实现时钟网页

【前端】实现时钟网页 文章目录 【前端】实现时钟网页项目介绍代码效果图 项目介绍 时钟显示在网页中央,并且使网页能够切换白天和夜晚两种模式。搭建基本的html结构,动态得到实时的时,分,秒 通过Date()函数获得。将得到的数字根…

力扣爆刷第153天之TOP100五连刷26-30(接雨水、环形链表、最长上升子序列)

力扣爆刷第153天之TOP100五连刷26-30(接雨水、环形链表、最长上升子序列) 文章目录 力扣爆刷第153天之TOP100五连刷26-30(接雨水、环形链表、最长上升子序列)一、300. 最长递增子序列二、415. 字符串相加三、143. 重排链表四、42.…

Flutter页面状态保留策略

目的: 防止每次点击底部按钮都进行一次页面渲染和网络请求 1. 使用IndexedStack 简单,只需要把被渲染的组件外部套一层IndexedStack即可 缺点: 在应用启动的时候,所有需要保存状态的页面都会直接被渲染,保存起来. 对性能有影响 2. 使用PageController 实现较为复杂,但是不用…

软件构造 | 期末查缺补漏

软件构造 | 期末查缺补漏 总体观 软件构造的三维度八度图是由软件工程师Steve McConnell提出的概念,用于描述软件构建过程中的三个关键维度和八个要素。这些维度和要素可以帮助软件开发团队全面考虑软件构建的方方面面,从而提高软件质量和开发效率。 下…

利用LinkedHashMap实现一个LRU缓存

一、什么是 LRU LRU是 Least Recently Used 的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。 简单的说就是,对于一组数据,例如:int[] a {1,2,3,4,5,6},…

2024年6月26日 (周三) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键,实现一键唤起、一键隐藏的 Windows 工具,并且支持窗口动态绑定快捷键(无需设置自动实现)。 土豆录屏: 免费、无录制时长限制、无水印的录屏软件 《Granblue Fantasy Versus: Risi…

PS教程29

图层蒙版 以案例来解释蒙版的作用 将这两张图片原框背景切换将图二的背景选中使用套索工具选中区域切换图一CtrlA全选CtrlC复制编辑-选择性粘贴-贴入即可贴入如果位置不对用移动工具进行调整 这就是图层蒙版 图层蒙版本质作用:是临时通道,支持黑白灰三种…

Linux开发讲课16--- 【内存管理】页表映射基础知识2

ARM32页表和Linux页表那些奇葩的地方 ARM32硬件页表中PGD页目录项PGD是从20位开始的,但是为何头文件定义是从21位开始? 历史原因:Linux最初是基于x86的体系结构设计的,因此Linux内核很多的头文件的定义都是基于x86的&#xff0c…

Java中Collection的成员及其特点

Collection集合 list集合系列 ArrarList集合 底层基于数组来实现 查询速度快(根据索引查询数据) 删除效率低(可能需要把后面很多的数据往后移) 添加效率…

软件构造 | Abstract Data Type (ADT)

软件构造 | Abstract Data Type (ADT) ​ 抽象数据类型与表示独立性:如何设计良好的抽象数据结构,通过封 装来避免客户端获取数据的内部表示(即“表示泄露”),避免潜在 的bug——在client和implementer之间建立“防火…

鸿蒙开发Ability Kit(程序框架服务):【FA模型切换Stage模型指导】 配置文件差异

配置文件的差异 FA模型应用在[config.json文件]中描述应用的基本信息,一个应用工程中可以创建多个Module,每个Module中都有一份config.json文件。config.json由app、deviceConfig和module三部分组成,app标签用于配置应用级别的属性&#xff…

裸机与操做系统区别(RTOS)

声明:该系列笔记是参考韦东山老师的视频,链接放在最后!!! rtos:这种系统只实现了内核功能,比较简单,在嵌入式开发中,某些情况下我们只需要多任务,而不需要文件…

前端项目结构介绍与Vue-cli(脚手架)环境搭建

传统的前端项目结构 一个项目中有许多html文件 每一个html文件都是相互独立的 如果需要在页面中导入一些外部依赖的组件(vue.js,elementUI),就需要在每一个html文件中引用都导入,十分的麻烦 而且这些外部组件都需要在其官网中自行下载,也增加了导入的繁琐程度 当今的前端项…

PMBOK® 第六版 实施整体变更控制

目录 读后感—PMBOK第六版 目录 对于变化的态度,个人引用两句加以阐释,即“流水不腐,户枢不蠹”与“不以规矩,不能成方圆”。这看似相互矛盾,实则仿若两条腿总是一前一后地行进。有一个典型的例子,“自由美…

基于IM948(Low-cost IMU+蓝牙)模块的高精度PDR(Pedestrian Dead Reckoning)定位系统 — 可以提供模块和配套代码

一、背景与意义 行人PDR定位系统中的PDR(Pedestrian Dead Reckoning,即行人航位推算)背景意义在于其提供了一种在GPS信号不可用或不可靠的环境下,对行人进行精确定位和导航的解决方案。以下是关于PDR背景意义的详细描述&#xff1…

Python代码打包成exe应用

目录 一、前期准备 二、Pyinstaller打包步骤 Pyinstaller参数详解 三、测试 Spec 文件相关命令 一、前期准备 (1)首先,我们需要确保你的代码可以在本地电脑上的pycharm正常运行成功。 (2)我们要先安装Pyinstalle…