SpringMVC - 05拦截器
(1)拦截器(interceptor)的作用
SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(Interceptor Chain)。
在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。
(2)拦截器和过滤器的区别
区别 | 过滤器 | 拦截器 |
使用范围 | 是Servlet规范中的一部分,任何Java Web工程都可以使用 | 是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用 |
拦截范围 | 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截 | 只会拦截访问的控制器方法,如果访问的是jsp/html/css/image或者js,是不会进行拦截的 |
(3)拦截器快速入门
(3.1)初始业务代码
@Controller public class TargetController { @RequestMapping("/target") public ModelAndView show(){ System.out.println("目标资源执行了......"); ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("name","zhangsan"); modelAndView.setViewName("index"); return modelAndView; } }
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>Hello world! ${name}-${age}</h1> </body> </html>
(3.2)创建拦截器,实现HandlerInterceptor接口
public class MyInterceptor1 implements HandlerInterceptor { // 在目标方法执行前执行 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException { System.out.println("preHandler......"); // return true; // 返回true 代表 放行 String param = request.getParameter("param"); if("yes".equals(param)){ return true; }else { request.getRequestDispatcher("/error.jsp").forward(request,response); return false; } } // 在目标方法执行后, 视图返回之前 执行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { modelAndView.addObject("name","beapx"); System.out.println("postHandle......"); } // 在流程都执行完毕后执行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("afterCompletion......"); } }
(3.3)在spring-mvc.xml配置拦截器
<!--1. 配置MVC--> <mvc:annotation-driven/> <!--2. 配置视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> <!--3. 配置静态资源权限开放--> <mvc:default-servlet-handler/> <!--4. 组件扫描 扫描controller--> <context:component-scan base-package="com.bearpx.spring.interceptor"></context:component-scan> <!-- 配置拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <!--对哪些资源执行拦截操作--> <bean class="com.bearpx.spring.interceptor.MyInterceptor1"/> </mvc:interceptor> </mvc:interceptors>
(3.4)测试
> 请求URL地址: http://localhost:8080/target?param=yes 正常放行
preHandler......
目标资源执行了......
postHandle......
afterCompletion......
> 请求URL地址:http://localhost:8080/target?param=sss 阻断
preHandler......
(3.5) 新增一个拦截器
public class MyInterceptor2 implements HandlerInterceptor { // 在目标方法执行前执行 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException { System.out.println("preHandler222222......"); return true; // 返回true 代表 放行 } // 在目标方法执行后, 视图返回之前 执行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { modelAndView.addObject("age",18); System.out.println("postHandle22222......"); } // 在流程都执行完毕后执行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("afterCompletion222222......"); } }
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.bearpx.spring.interceptor.MyInterceptor1"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.bearpx.spring.interceptor.MyInterceptor2"/> </mvc:interceptor> </mvc:interceptors>
(3.6)再次测试
> 请求URL地址: http://localhost:8080/target?param=yes 正常放行
preHandler......
preHandler222222......
目标资源执行了......
postHandle22222......
postHandle......
afterCompletion222222......
afterCompletion......
> 请求URL地址:http://localhost:8080/target?param=sss 阻断
preHandler......
(3.7)拦截器配置顺序
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.bearpx.spring.interceptor.MyInterceptor2"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.bearpx.spring.interceptor.MyInterceptor1"/> </mvc:interceptor> </mvc:interceptors>
> 请求URL地址:http://localhost:8080/target?param=sss 阻断
preHandler222222......
preHandler......
afterCompletion222222......
拦截器起作用与在配置文件中的配置顺序有关系。
(3.8)拦截器方法说明
方法名 | 说明 |
preHandle()
|
方法将在请求处理之前进行调用,该方法的返回值是布尔值Boolean类型的,当它返回为false时,表示请求结束,后续的Interceptor和Controller都不会再执行,
当返回值为true时就会继续调用下一个Interceptor的preHandle方法
|
postHandle()
|
该方法是在当前进行处理之后被调用,前提是preHandle方法的返回值为true时才能被调用,且它会在DispatcherServlet 进行视图返回渲染之前被调用,
所以我们可以在这个方法中对Controller处理之后的ModelAndView对象进行操作
|
afterCompletion()
|
该方法将在整个请求结束之后,也就是在DispatcherServlet渲染了对应的视图之后执行,前提是preHandle方法的返回值为true时才能被调用
|