SpringMVC拦截器的基本使用
1.拦截器(interceptor)的作用
(1)SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
(2)将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(interceptor Chain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体体现。
2.拦截器和过滤器的区别
(1)使用范围:
①过滤器(Filter)是servlet规范中的一部分,任何JavaWeb工程都可以使用
②拦截器(interceptor)是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
(2)拦截范围:
①过滤器(Filter)在url-pattern 中配置了 /* 之后,可以对所有要访问的资源进行拦截
②拦截器(interceptor)在<mvc:mapping path=" "/>中配置了 /** 之后,也可以对所有资源进行拦截,但是可以
通过<mvc:exclude-mapping path=" "/>标签排除不需要拦截的资源
3 HandlerInterceptor接口的方法
(1) preHandle()方法
该方法将在请求处理之前被调用。SpringMVC中的Interceptor是链式的调用,在一个应用或一个请求中
可以同时存在多个Interceptor。每个Interceptor的调用会依据它的声明顺序依次执行,而且最先执行的
都是Interceptor中的preHandle()方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前
请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回
值是布尔值类型,当返回false时,表示请求结束,后续的Interceptor和Controller都不会再执行;当返
回值true时,就会继续调用下一个Interceptor的preHandle方法,如果已经是最后一个Interceptor的
时,就会调用当前请求的Controller方法。
(2) postHandle()方法
该方法将在当前请求进行处理之后,也就是Controller方法调用之后执行,但是它会在
DispatcherServlet进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller处理之后的
ModelAndView对象进行操作。postHandle方法被调用的方向跟preHandle是相反的,也就是说先声明
的Interceptor的postHandle方法反而会后执行。如果当前Interceptor的preHandle()方法返回值为
false,则此方法不会被调用。
(3) afterCompletion()方法
该方法将在整个当前请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行。这个方法
的主要作用是用于进行资源清理工作。如果当前Interceptor的preHandle()方法返回值为false,则此方
法不会被调用。
4.拦截器的使用步骤
(1)创建拦截器类实现HandlerInterceptor接口
//定义处理器拦截器 public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getSession().getAttribute("uid") == null) { response.sendRedirect("/web/login.html"); return false; // 返回false代表不放行 } return true; // 返回true代表放行 } }
(2)配置拦截器
//注册处理器拦截器 @Configuration public class LoginInterceptorConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 创建拦截器对象 HandlerInterceptor interceptor = new LoginInterceptor(); // 添加白名单 List<String> patterns = new ArrayList<>(); patterns.add("/bootstrap3/**"); patterns.add("/css/**"); patterns.add("/images/**"); patterns.add("/js/**"); patterns.add("/web/login.html"); patterns.add("/web/register.html"); patterns.add("/web/index.html"); patterns.add("/web/product.html"); patterns.add("/users/reg"); patterns.add("/users/login"); patterns.add("/districts/**"); patterns.add("/products/**"); // 通过注册工具添加拦截器 registry.addInterceptor(interceptor).addPathPatterns("/**").excludePathPatterns(patterns); } }
①addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
②addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns(“/**”)对所有请求都拦截
③excludePathPatterns:用于设置不需要拦截的过滤规则