handlerInterceptor
SpringMVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器(handler)进行预处理和后处理。
接口中提供了3个方法
prehandle
posthandle
afterCompletion
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.web.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
上面代码中的参数modelAndView和ex都可以不传。
default表示这些方法可以不实现。
示意图:
preHandle:
预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器
返回值
true表示继续流程(如调用下一个拦截器或处理器);
false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
postHandle:
后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
afterCompletion:
整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。
入门案例:
- 注册组件
- 在springmvc的配置文件中
interceptor的顺序 → 该interceptor在执行链的什么位置
- 测试
prehandle返回值改为false
posthandle方法中可以修改ModelAndView
若是handler返回json数据,postHandler接收的ModelAndView就为null
Interceptor的作用范围
默认是DispatcherServlet的作用范围/
能否修改interceptor的作用范围呢?
/**就代表dispatchServlet范围内的所有请求。
多个interceptor的执行情况
- 注册组件
- SpringMVC配置文件中配置interceptor
在interceptor标签中的书写顺序就是interceptor的执行顺序。
- prehandle返回值均为true的执行顺序
执行结果:
prehandle的返回值为false
规律:
1、当prehandle返回值为true可以继续向下执行,并且它对应的执行过的nterceptor中的afterCompletion一定可以执行到
2、当prehandle返回值为false,不可继续向下执行。
a. prehandle1为false
b. prehandle2为false
c. prehandle3为false
d. 提问环节
如果4个interceptor,prehandle 123为true 4为false → 1234 321
如果5个interceptor,prehandle 1245为true,3为false → 12321
如果5个interceptor,prehandle 2345为true,1为false →
不管你有几个interceptor,不管intercepter中的prehandle为true还是false
作业:login页面(利用interceptor来做)
login请求 → 完成login请求之后,就可以访问其他的任意请求
如果login请求失败 → 就重定向(或者转发)到login.jsp
实现一个登陆页面。
并使用SpringMVC的interceptor增加一个功能:没有登陆的用户立即返回到登录页面。
登陆的用户可以访问其他的请求
代码见Homework09