Spring MVC 的拦截器
1,Demo
SpringMVC的拦截器需要实现HandlerInterceptorAdapter的接口 对应提供了三个preHandle,postHandle,afterCompletion方法。
preHandle在业务处理器处理请求之前被调用,
postHandle在业务处理器处理请求执行完成后,生成视图之前执行,
afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等 。所以要想实现自己的权限管理逻辑,需要继承HandlerInterceptorAdapter并重写其三个方法。
实现了HandlerInterceptorAdapter接口之后,再在xml文件中进行必要的拦截配置就可以了
public class Interceptor1 extends HandlerInterceptorAdapter { //在目标方法之前执行 /* * 这个返回值很重要 * 如果返回了false,那么后前的其他的拦截器以及目标方法都不能执行了。 * 就是返回false,Spring mvc框架对应的函数就直接return了 * 这里的前置拦截,多用于一些认证之类的行为,比如,没有登录的用户的请求都来接下来,转到登录页面 * */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); return true; } //目标方法之后,渲染视图之前执行,可以对视图和模型做进一步渲染或修改 @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("completion"); } }
这里说一下HandlerInterceptorAdapter ,这个类是实现了HandlerInterceptor 接口的一个子类,为每一方法都提供的空的实现,
这样我们继承了Adapter之后,只需要重写想要的方法就可以了,不需要实现每一个方法。
拦截器在xml中的配置如下
<mvc:interceptors> <bean class="com.zview.Interceptor.Interceptor1"></bean> </mvc:interceptors>
2,拦截器的配置
拦截器可以定义很多个,可以针对于每一个请求做精细化的处理
<mvc:interceptors> <bean class="com.zview.Interceptor.Interceptor1"></bean> <mvc:interceptor> <mvc:mapping path="/add"/> <bean class="com.zview.Interceptor.Interceptor2"></bean> </mvc:interceptor> <mvc:interceptor> <mvc:exclude-mapping path="/zz"/> <mvc:mapping path="/**"/> <bean class="com.zview.Interceptor.Interceptor3"></bean> </mvc:interceptor> </mvc:interceptors>
定义在外面的Interceptor1,是全部都要拦截的,Interceptor2只拦截指定的url,Interceptor3拦截指定url以外除了/zz是不拦截的。注意就是说拦截的一定要定义
3,拦截器的执行顺序
如果有多个拦截器,ABC。他们的执行顺序和定义顺序有关。
其中preHandle是先定义先执行,其他两个是后定义先执行。
特殊的,如果B拦截器的preHander返回了false,那么C不执行。A的afterCompletion会执行,而B的afterCompletion不会执行
如下: A-pre B-pre C-pre C-post B-post A-post C-after B-after A-after
B返回false的话: A-pre B-pre A-after