目录
定义拦截器
public class HandlerInterceptor1 implements HandlerInterceptor {
//在执行handler之前来执行的
//用于用户认证校验、用户权限校验
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("HandlerInterceptor1...preHandle");
//如果返回false表示拦截不继续执行handler,如果返回true表示放行
return true;
}
//在执行handler返回modelAndView之前来执行
//如果需要向页面提供一些公用 的数据或配置一些视图信息,使用此方法实现 从modelAndView入手
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("HandlerInterceptor1...postHandle");
}
//执行handler之后执行此方法
//作系统 统一异常处理,进行方法执行性能监控,在preHandle中设置一个时间点,在afterCompletion设置一个时间,两个时间点的差就是执行时长
//实现 系统 统一日志记录
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("HandlerInterceptor1...afterCompletion");
}
}
public class HandlerInterceptor2 implements HandlerInterceptor {
//在执行handler之前来执行的
//用于用户认证校验、用户权限校验
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("HandlerInterceptor2...preHandle");
//如果返回false表示拦截不继续执行handler,如果返回true表示放行
return true;
}
//在执行handler返回modelAndView之前来执行
//如果需要向页面提供一些公用 的数据或配置一些视图信息,使用此方法实现 从modelAndView入手
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("HandlerInterceptor2...postHandle");
}
//执行handler之后执行此方法
//作系统 统一异常处理,进行方法执行性能监控,在preHandle中设置一个时间点,在afterCompletion设置一个时间,两个时间点的差就是执行时长
//实现 系统 统一日志记录
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("HandlerInterceptor2...afterCompletion");
}
}
拦截器要实现HandlerInterceptor接口,或者继承已经实现了HandlerInterceptor接口的抽象类
- preHandle在执行Controller的方法之前调用。可以有多个拦截器,每个拦截器的调用会依据它的声明顺序依次执行。如果该方法的返回值为false,后续的拦截器和Controller都不会再执行,为true,则可以继续执行。
- postHandle:在Controller方法调用之后,DispatcherServlet 进行视图返回渲染之前(返回modelandview)被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。
- afterCompletion:在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。
在springmvc.xml中配置
<!--拦截器 -->
<mvc:interceptors>
<!--多个拦截器,顺序执行 -->
<mvc:interceptor>
<!-- /**可以拦截所有路径不管多少层 -->
<mvc:mapping path="/**" />
<bean class="cn.itcast.springmvc.interceptor.HandlerInterceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="cn.itcast.springmvc.interceptor.HandlerInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
测试
在浏览器中随意输入一个方法
当两个浏览器返回都为true时,打印结果为
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor2...postHandle
HandlerInterceptor1...postHandle
HandlerInterceptor2...afterCompletion
HandlerInterceptor1...afterCompletion
当都为false时
HandlerInterceptor1...preHandle
当第一个拦截器为true,第二个拦截器为false时
HandlerInterceptor1...preHandle
HandlerInterceptor2...preHandle
HandlerInterceptor1...afterCompletion
总结:
拦截器1放行,拦截器2 preHandle才会执行。
拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。
只要有一个拦截器不放行,postHandle不会执行。
比如:统一日志处理拦截器,需要该拦截器preHandle一定要放行,且将它放在拦截器链接中第一个位置。
比如:登录认证拦截器,放在拦截器链接中第一个位置。权限校验拦截器,放在登录认证拦截器之后(因为登录通过后才校验权限)
拦截器应用