Java – SpringMVC – 拦截器interceptor
简介
SpringMVC 对控制器执行方法提供一种拦截器,可在控制器执行前,执行后,等时刻拦截并可自定义执行方法。
配置拦截器
创建拦截器类
SpringMVC中的拦截器需要实现HandlerInterceptor
,可以创建一个【interceptor】
目录,专门用于存放拦截器类的包,该类中需要实现【HandlerInterceptor】
接口中的三个方法。
public class firstInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
preHandle
: 表示将在控制器方法执行前拦截并执行的方法。其boolean类型的返回值表示是否拦截或放行,返回true
为放行,即调用控制器方法;返回false
表示拦截,即不调用控制器方法
postHandle
: 控制器方法执行之后执行的方法。
afterCompletion
: 处理完视图和模型数据,渲染视图完毕之后执行的方法。
配置拦截器
创建完拦截器后,需要配置到Bean中,由IoC管理,配置Bean有三种方法。
在Bean XML文件中,可以使用【mvc:interceptors】
进行配置
方法一:Bean 配置
对于一个实现了【HandlerInterceptor】
接口的类而言,它就是一个拦截器,所以可以以一个Bean对象的方式创建拦截器。
以Bean对象的方式创建拦截器
<mvc:interceptors>
<bean class="cn.unsoft.interceptor.firstInterceptor"></bean>
</mvc:interceptors>
注意:使用Bean对象配置的拦截器,会对所有的请求都拦截下来,包含不存在的URL请求。
方法二:ref 引用配置
我们可以在Bean XML 中配置好一个Bean对象,并使用 ref
引用这个Bean 对象。
使用 XML 配置 Bean 方法配置拦截器
<bean id="firstInterceptor" class="cn.unsoft.interceptor.firstInterceptor"></bean>
<mvc:interceptors>
<ref bean="firstInterceptor"></ref>
</mvc:interceptors>
也可以通过【注解+扫描】
的方式,自动配置Bean对象,SpringMVC会自动帮我们把Bean类设置id为小驼峰,可以使用 ref="id名"
来配置拦截器。
我们需要在拦截器上,加上注解
@Component
public class firstInterceptor implements HandlerInterceptor { }
扫描增加【interceptor】
目录
<context:component-scan base-package="cn.unsoft.interceptor"></context:component-scan>
使用 ref
引用拦截器类
<mvc:interceptors>
<ref bean="firstInterceptor"></ref>
</mvc:interceptors>
注意:使用 ref
对象配置的拦截器,会对所有的请求都拦截下来,包含不存在的URL请求。
方法三:mvc:interceptor 配置
【mvc:interceptor】
配置拦截器可以精确哪些请求需要拦截,哪些不需要拦截。
【mvc:mapping】
子标签 : 配置需要拦截的路径
【mvc:exclude-mapping】
子标签 : 配置排除拦截的路径
例子:对 /abc 请求进行拦截
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/abc"></mvc:mapping>
<ref bean="firstInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
对于 /abc 以外的请求路径,不会拦截,对 /abc 的请求,会使用【firstInterceptor】
拦截器拦截。
例子:对所有请求进行拦截
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"></mvc:mapping>
创建完拦截器路径后,必须定义处理的拦截器类
<ref bean="firstInterceptor" />
或
<bean class="cn.unsoft.interceptor.firstInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
注意:对所有请求进行拦截时,需要配置路径是【/**】
而不是【/*】
【/*】
只会对单级目录产生影响,如“/abc”但是对多级目录则会失效,如“/abc/a”
【/**】
对所有级目录产生影响,即不管是“/abc”还是“/abc/a”也会生效。
拦截器执行顺序
如创建多个拦截器时,它们顺序与 Bean XML 文件中定义的拦截器顺序有关。
preHandle 方法执行会按照 Bean XML 文件中定义的拦截器顺序正序执行 => {1->2->3...}
postHandle 和 afterCompletion 方法执行会按照 Bean XML 文件中定义的拦截器顺序倒序执行 => {...3->2->1}
多个拦截器中有一个拦截器preHandle返回false的情况
根据底层源码中可得:
1.当第一个拦截器preHandle返回false时,只有第一个拦截器preHandle执行,其它拦截器将不执行。
2.当第二个以后拦截器preHandle返回false时,会调用到第二个拦截器preHandle,后面的拦截器preHandle都不再执行,并且执行第一个拦截器afterCompletion方法
举例:若有5个拦截器,第三个拦截器preHandle返回false时
interceptor1 => preHandle.true
interceptor2 => preHandle.true
interceptor3 => preHandle.false
interceptor4 => preHandle.true
interceptor5 => preHandle.true
结果:
interceptor1.preHandle
interceptor2.preHandle
interceptor3.preHandle // 发现返回了 false
interceptor2.afterCompletion
interceptor1.afterCompletion
共有 0 条评论