拦截器
1、自定义拦截器概述
Spring MVC也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现HandlerInterceptor接口,也可以继承HandlerInterceptorAdapter适配器类。
① preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求 request 进行处理。如果程序员决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true;如果程序员决定不需要再调用其他的组件去处理请求,则返回false。
② postHandle():这个方法在业务处理器处理完请求后,但是DispatcherServlet 向客户端返回响应前被调用,在该方法中对用户请求request进行处理。
③ afterCompletion():这个方法在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
2、单个拦截器
(1)自定义拦截器类
public class FirstHandlerInterceptor implements HandlerInterceptor {
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
System.out.println(this.getClass().getName() + " - afterCompletion");
}
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
System.out.println(this.getClass().getName() + " - postHandle");
}
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
System.out.println(this.getClass().getName() + " - preHandle");
return true;
}
}
(2)注册拦截器
<!-- 注册拦截器 -->
<mvc:interceptors>
<!-- 拦截通过中央调度器过滤的所有请求 -->
<bean id="firstHandlerInterceptor"
class="spring_upload.FirstHandlerInterceptor"/>
</mvc:interceptors>
(3)控制器
@Controller
public class TestController {
@RequestMapping("/hello")
public String Hello() {
System.out.println("+++++");
return "success";
}
}
(4)测试
<a href="${pageContext.request.contextPath}/hello">测试拦截器</a>
(5)结果
spring_upload.FirstHandlerInterceptor - preHandle
+++++
spring_upload.FirstHandlerInterceptor - postHandle
spring_upload.FirstHandlerInterceptor - afterCompletion
3、多个拦截器
(1)再定义一个拦截器
public class MySecondInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//return true;请求继续提交 return false;请求不再提交
System.out.println(this.getClass().getName() + "======>preHandle");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println(this.getClass().getName() + "======>postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println(this.getClass().getName() + "======>afterCompletion");
}
}
(2)配置拦截器
<!-- 注册拦截器 -->
<mvc:interceptors>
<!-- 拦截通过中央调度器过滤的所有请求 -->
<bean id="myFirstInterceptor"
class="com.atguigu.springmvc.interceptors.MyFirstInterceptor"/>
<!-- <ref bean="myFirstInterceptor"/> -->
<!-- 配置拦截器,指定拦截什么请求,以及不拦截什么请求 -->
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<!-- <mvc:exclude-mapping path=""/> -->
<bean id="mySecondInterceptor"class="spring_upload.MySecondInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
(3)结果
spring_upload.MyFirstInterceptor======>preHandle
spring_upload.MySecondInterceptor======>preHandle
spring_upload.MyFirstInterceptor======>afterCompletion
4、 多个拦截方法的执行顺序
spring_upload.FirstHandlerInterceptor - preHandle
spring_upload.interceptors.SecondHandlerInterceptor – preHandle
************************************biz method*******************************
spring_upload.SecondHandlerInterceptor - postHandle
spring_upload.FirstHandlerInterceptor - postHandle
spring_upload.SecondHandlerInterceptor - afterCompletion
spring_upload.FirstHandlerInterceptor - afterCompletion
4.1、多个拦截器的执行顺序以及方法的执行情况
[1]多个拦截器的执行顺序:根据配置顺序来决定,先配置的先执行。
[2]方法的执行情况:
preHanle: 与拦截器的执行顺序一致
postHandle: 与拦截器的执行顺序相反
afterCompletion: 与拦截器的执行顺序相反
preHandle方法的返回值:
如果返回true,代表请求可以正常往后执行
如果返回false,代表请求被拦截住,不能继续往后执行
如果是第一个拦截器的preHandle返回false,则后续的操作都不执行,如果不是第一个拦截器的preHandle返回false, 之前拦截器的preHandle以及afterCompletion都会执行。
如果返回true,代表请求可以正常往后执行
如果返回false,代表请求被拦截住,不能继续往后执行
如果是第一个拦截器的preHandle返回false,则后续的操作都不执行,如果不是第一个拦截器的preHandle返回false, 之前拦截器的preHandle以及afterCompletion都会执行。