SpringMVC-16-拦截器入门
1、定义拦截器的 bean
拦截器(Interceptor)的代码和 aop 很相似,实现 handlerinterceptor 接口,重写其中的 preHandle,postHandle,afterCompletion 三个函数
- preHandle 函数:执行在 Controller 方法之前,返回一个 boolean 值,返回 true 则放行,返回 false 则阻止且不再进行后续操作
- postHandle 函数:执行在 Controller 方法之后,dispatcherServlet 进行视图的渲染之前,参数中有 modelAndView,可以对其进行操作
- afterCompletion 函数:执行在 dispatcherServlet 进行视图的渲染之后
执行流程:preHandle函数 -> Controller方法 -> postHandle函数 -> dispatcherServlet渲染试图 -> afterCompletion函数
如果 preHandle函数返回 false,那么后续的操作都不会发生
@Component
public class ProjectInterceptor implements handlerinterceptor {
// 模拟判断请求中是否包含代表已经登录的 cookie,是则放行,否则阻止
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...");
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
if (cookie.getName().equals("hasLogged") && cookie.getValue().equals("true")) {
cookie.setMaxAge(60 * 60 * 24 * 7); // 若已登录,刷新 cookie 持续时间
response.addCookie(cookie);
return true;
}
}
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<center>请先登录。<center/>");
return false;
}
@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...");
}
}
[补充]
2、定义配置类
拦截器的配置类和设置静态资源放行的配置类同样继承自 WebMvcConfigurationSupport,而且设置方法也很相似,要重写 addInterceptors 方法
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
// 自动装配拦截器
@Autowired
private ProjectInterceptor interceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
// 添加拦截器,前为拦截器对象实例,后为需要拦截的路径
registry.addInterceptor(interceptor).addpathPatterns("/books", "/books/*");
}
}
3、使 SpringMVC 配置类能够扫描到拦截器和配置类
// 拦截器在 controller 包下,配置类在 config 包下
@Configuration
@ComponentScan({"com.mzz.controller", "com.mzz.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
4、简化开发
SpringMVC 的核心配置类可以实现 WebMvcConfigurer 接口,再重写其中的 addInterceptors 方法,就不需要再单独定义拦截器的配置类,相当于合并了前面的第 2、3 步
同样的,处理放行静态资源的 addResourceHandlers 方法也在此接口中,可以一并重写,如下例
@Configuration
@ComponentScan({"com.mzz.controller"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
@Autowired
private ProjectInterceptor interceptor;
// 添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor).addpathPatterns("/books", "/books/*");
}
// 处理静态资源
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/page/**").addResourceLocations("/html/");
}
}
然而这种形式侵入性较强,了解即可