1. SpringMVC的拦截器
针对请求和响应进行的额外的处理.在请求和响应的过程中添加预处理,后处理和最终处理.
2. 拦截器的应用场景
1、日志记录:记录请求信息的日志
2、权限检查,如登录检查
3、性能检测:检测方法的执行时间
3. 拦截器执行的时机
- preHandle():在请求被处理之前进行操作,预处理
- postHandle():在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果,后处理
- afterCompletion:所有的请求响应结束后执行善后工作,清理对象,关闭资源 ,最终处理.
4. 拦截器实现的两种方式
- 继承HandlerInterceptorAdapter的父类
- 实现HandlerInterceptor接口,实现的接口,推荐使用实现接口的方式
HandlerInterceptor接口分析
自定义拦截器,需要实现 HandlerInterceptor 接口。而该接口中含有三个方法:
(1) preHandle
该方法在处理器方法执行之前执行。其返回值为 boolean,若为 true,则紧接着会执行处理器方法,且会将 afterCompletion()方法放入到一个专门的方法栈中等待执行。
(2) postHandle
该方法在处理器方法执行之后执行。处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处理器方法执行完后执行,且该方法参数中包含 ModelAndView,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。
(3)afterCompletion
当preHandle()方法返回 true 时,会将该方法放到专门的方法栈中,等到对请求进行响应的所有工作完成之后才执行该方法。即该方法是在中央调度器渲染(数据填充)了响应页面之后执行的,此时对 ModelAndView 再操作也对响应无济于事。afterCompletion 最后执行的方法,清除资源,例如在 Controller 方法中加入数据等。
5.自定义拦截器实现权限验证
-
登录方法,在session中存储用户信息,用于进行权限验证
// 登录的业务判断 @RequestMapping("/login") public String login(String name, String pwd, HttpServletRequest request){ if ("admin".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){ // 在session中存储用户信息,用于进行权限验证 request.getSession().setAttribute("user", name); return "main"; }else { request.setAttribute("msg", "用户名或密码不正确"); return "login"; } }
-
开发拦截器的功能.实现HandlerInterceptor接口,重写preHandle()方法
package com.powernode.interceptor; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 判断是否登录过 if (request.getSession().getAttribute("user") == null){ // 没有登录,返回登录页面 request.setAttribute("msg","请登录"); request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); return false; } return true; } }
-
在springmvc.xml文件中注册拦截器
<!--注册拦截器--> <mvc:interceptors> <mvc:interceptor> <!--映射要拦截的请求--> <mvc:mapping path="/**"/> <!--设置放行的请求--> <mvc:exclude-mapping path="/showLogin"/> <mvc:exclude-mapping path="/login"/> <!--配置具体的拦截器实现功能的类--> <bean class="com.powernode.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>