拦截器interceptor总结

文章介绍了拦截器的概念,包括它与AOP和过滤器的区别。在SpringMVC中,拦截器用于在控制器方法执行前后添加增强或进行权限控制。配置拦截器涉及定义拦截器bean、配置类以及执行流程。文中以校验登录为例,展示了如何定义拦截器类,利用ThreadLocal存储用户信息,以实现登录验证和用户信息的便捷获取。
摘要由CSDN通过智能技术生成

一. 概念

引入
消息从浏览器发送到服务端,请求会先到达Tomcat服务器;
将请求划分成动态、静态资源;处理动态;
动态的资源经过Filter过滤器;
过滤器放行后才是Spring,中央控制器会根据访问分发到controller中;
controller操作执行完后,返回数据给浏览器;

当如果想让每个controller被访问之前和后做一件事---- 拦截器

在这里插入图片描述
如:权限控制,需要看访问是否有权限访问这个controller;

定义:拦截器是一种动态拦截方法调用的机制,在SpringMVC中动态拦截controller方法的执行;

作用
1. 在指定的方法调用前后执行预先设定的代码(增强);
2. 阻止原始方法的执行(如权限控制)

拦截器和AOP的区别:

AOP是原始方法确定会被调用,在调用前后做增强处理,拦截器不仅能增强,还决定你能不能调用方法;

拦截器和过滤器的区别:

1.归属不同,Filter属于Servlet技术,Interceptor拦截器属于SpringMVC技术;
SpringMVC的功能可以在拦截器中操作,但不能在Filter中操作;
2.拦截范围不同:
Filter过滤器是在Tomcat服务器阶段配置,能对所有请求进行增强;
拦截器仅仅是对SpringMVC阶段操作,SpringMVC能接受哪些访问取决于容器启动配置中的设置:

二. 配置方法

2.1 定义拦截器bean

(1)在controller层新建一个拦截器层,创建一个自定义interceptor拦截器类,配置成bean;
在这里插入图片描述

(2)自定义拦截器类 实现 HandlerInterceptor,并重写preHandlepostHandleafterCompletion三个方法;

拦截器是bean,要添加 @Component注解

preHandle方法返回false会终止原始操作,原始操作后面的也不再执行;而true会都执行。可以用此增加判断逻辑,满足则true,不满足则false。
在这里插入图片描述

(3)让SpringMVC加载到拦截器bean;
保证SpringMVC能扫描到:
此时拦截器类就在controller目录下,不需要改;
在这里插入图片描述

2.2 定义配置类

(1)在config包下定义一个SpringMvcSupport配置类,类似addResourceHandlers分发者服务,继承WebMvcConfiguartionSupport实现 addIntercepter方法;
在这里插入图片描述

(2)将之前定义的拦截器类ProjectInterceptor的bean注入,
再指定路径,如当调用“/books”请求时拦截;
在这里插入图片描述
(3)让SpringMVC能扫描到配置类:
在这里插入图片描述

效果
在这里插入图片描述
后台:
可以看出,通过拦截器对原有方法增强了;除此之外也可以 preHandle 返回false,则拦截;
在这里插入图片描述

注意:
只有books 才会被拦截;而books/100 不会被拦截!
改: books, books/* 即可;

2.3 执行流程

在拦截器类中,preHandle方法返回false会终止原始方法及其之后的所有操作;而返回true会都执行。
在这里插入图片描述

2.4 简化方法:将拦截器类配置到SpringMvcConfig中 ★

只需要两步:
① 定义拦截器类
②在SpringMvcConfig中去配置拦截器类
在这里插入图片描述

缺点:拦截器类和Spring绑定在一起了,侵入性较强;

三. 案例:使用拦截器中校验登录

登陆验证即需要前端请求 /user/me页面,用来查询当前登录的用户信息;

问题1:当用户越来越多的时候,都需要校验用户的登录,不能每一个Controller中都来写业务逻辑;
解决:拦截器---------SpringMVC中动态拦截controller方法的执行,在所有的【controller之前】去执行!

问题2:拦截器校验完后还需要用户信息;
解决:用户信息缓存在ThreadLocal,后续业务就可以直接从Threadlocal获取用户;
(每个请求到服务都是独立的线程,如果不用ThreadLocal而是存于本地变量,则可能在多线程并发时修改的安全问题,而ThreadLocal会将数据存到线程内部的工作空间的map去保存,即每个线程都有独立的存储空间,相互之间没有干扰)
然后在controller中,通过threadLocal中取出User信息!

业务逻辑
在这里插入图片描述

(1)定义拦截器类

在utls层定义拦截器类,实现HandlerInterceptor,重写preHandleafterCompletion方法
在preHandle做用户校验的逻辑;
在afterCompletion销毁用户信息(ThreadLocal要主动remove(),防止内存泄漏);

①从request中可以获取session;
②获取session中的用户;
③判断用户是否存在;
④不存在则拦截
⑤存在则保存到ThreadLocal
⑥放行

在这里插入图片描述在这里插入图片描述

Threadlocal:
在utls层的UserHolder中,定义了ThreadLocal的相关方法,设为静态方便调用;
注意静态变量在【类加载】时就会自动初始化!
在这里插入图片描述

(2)配置拦截器

将拦截器类直接配置到SpringMvcConfig中(简化方法):
并设置拦截路径:排除掉不需要拦截就可以访问的路径(如shop店铺、blog博客)(也可以配置拦截哪些路径):
在这里插入图片描述

假设拦截器放行,则请求到达Controller,还需要完成剩余业务逻辑:
需要把当前登录的用户信息返回到前端:
之前在拦截其中把用户信息放到了UserHolder中的ThreadLocal中,只需要调用UserHolder类的静态方法get就可以取出;
在这里插入图片描述

  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值