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