目录
前言
本章节和之前的过滤器章节可以对比学习,方便记忆
快速入门
1.什么是拦截器
1)是一种动态拦截方法调用的机制,类似于过滤器。
2)拦截器是Spring框架中提供的,用来动态拦截控制器方法的执行。
2.拦截器的作用
用于拦截请求,在方法调用的前后,实现自己需要的业务逻辑
在拦截器当中,我们一般做一些通用性的操作,比如:我们可以通过拦截器来拦截前端发起的请求,将登录校验的逻辑全部编写在拦截器当中。在校验的过程当中,如发现用户登录了(携带JWT令牌且是合法令牌),就可以直接放行,去访问spring当中的资源。如果校验时发现并没有登录或是非法令牌,就可以直接给前端响应未登录的错误信息。
3.写一个简单的Demo
思路:
我们需要自定义拦截器(实现HandlerInterceptor接口,重写当中的方法)
然后需要配置一个拦截器(实现WebMvcConfigurer接口,并重写addInterceptors方法
自定义拦截器具体代码实现
//自定义拦截器
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
//目标资源方法执行前执行。 返回true:放行 返回false:不放行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle .... ");
return true; //true表示放行
}
//目标资源方法执行后执行
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle ... ");
}
//视图渲染完毕后执行,最后执行
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion .... ");
}
}
注意:这里我们的业务代码全部用语句println来代替,可以根据业务需求具体修改
配置一个拦截器具体代码实现
@Configuration
public class WebConfig implements WebMvcConfigurer {
//自定义的拦截器对象
@Autowired
private LoginCheckInterceptor loginCheckInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册自定义拦截器对象
registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");//设置拦截器拦截的请求路径( /** 表示拦截所有请求)
}
}
使用细节
1.拦截路径
在注册配置拦截器的时候,我们需要配置拦截器的拦截路径,通过addPathPatterns方法,就可以指定要拦截哪些资源。
在上面我们使用的是/**,表示拦截所有的路径,在配置拦截器的时候,我们还可以通过excludePathPatterns方法指定不拦截哪些资源
代码如下
@Configuration
public class WebConfig implements WebMvcConfigurer {
//拦截器对象
@Autowired
private LoginCheckInterceptor loginCheckInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册自定义拦截器对象
registry.addInterceptor(loginCheckInterceptor)
.addPathPatterns("/**")//设置拦截器拦截的请求路径( /** 表示拦截所有请求)
.excludePathPatterns("/login");//设置不拦截的请求路径
}
}
几种常用的拦截路径设置
/** 是一级路径,能匹配/depts,/emps,/login,不能匹配 /depts/1
/** 是任意路径,匹配所有路径
/depts/* 是/depts下的一级路径,能匹配/depts/1,不能匹配/depts/1/2,/depts
/depts/** 是/depts下的任意级路径,能匹配/depts,/depts/1,/depts/1/2,不能匹配/emps/1
2.执行流程
图解(过滤器和拦截器同时存在)
说明:
-
当我们打开浏览器来访问部署在web服务器当中的web应用时,此时我们所定义的过滤器会拦截到这次请求。拦截到这次请求之后,它会先执行放行前的逻辑,然后再执行放行操作。而由于我们当前是基于springboot开发的,所以放行之后是进入到了spring的环境当中,也就是要来访问我们所定义的controller当中的接口方法。
-
Tomcat并不识别所编写的Controller程序,但是它识别Servlet程序,所以在Spring的Web环境中提供了一个非常核心的Servlet:DispatcherServlet(前端控制器),所有请求都会先进行到DispatcherServlet,再将请求转给Controller。
-
当我们定义了拦截器后,会在执行Controller的方法之前,请求被拦截器拦截住。执行
preHandle()
方法,这个方法执行完成后需要返回一个布尔类型的值,如果返回true,就表示放行本次操作,才会继续访问controller中的方法;如果返回false,则不会放行(controller中的方法也不会执行)。 -
在controller当中的方法执行完毕之后,再回过来执行
postHandle()
这个方法以及afterCompletion()
方法,然后再返回给DispatcherServlet,最终再来执行过滤器当中放行后的这一部分逻辑的逻辑。执行完毕之后,最终给浏览器响应数据。
提问:
过滤器和拦截器同时存在的执行顺序如何?可以对照着过滤器章节自己定义一个过滤器和拦截器,看看执行顺序是怎样的
拦截器与过滤器的区别概述
1.实现的接口不同,过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。
2.拦截的范围不同,过滤器会拦截所有资源,而拦截器只能拦截spring环境下的资源