一.拦截器
- 定义拦截器,实现HandlerInterceptor接口
package com.huan.web;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Interceptor implements HandlerInterceptor{
//进入Handler方法之前执行
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
//return false表示拦截,不向下执行
//return true表示放行
return false;
}
//进入Handler方法之后,返回modelAndView之前执行
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
//执行Handle之后执行
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
- 可以从名称和参数看出各个接口的顺序和作用:
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
参数最少,只有三个
进入 Handler方法之前执行
用于身份认证、身份授权。比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception
多了一个modelAndView参数
进入Handler方法之后,返回modelAndView之前执行
应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) throws Exception
多了一个Exception的类型的参数
执行Handler完成执行此方法
应用场景:统一异常处理,统一日志处理
二.拦截器配置
- 针对HandlerMapping配置
springmvc拦截器针对HandlerMapping进行拦截设置,如果在某个HandlerMapping中配置拦截,经过该HandlerMapping映射成功的handler最终使用该拦截器。
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="handlerInterceptor1"/>
<ref bean="handlerInterceptor2"/>
</list>
</property>
</bean>
<bean id="handlerInterceptor1" class="com.huan.web.Interceptor1.Interceptor1"/>
<bean id="handlerInterceptor2" class="com.huan.web.Interceptor1.Interceptor2"/>
不推荐使用
- 类似全局的拦截器
springmvc配置类似全局的拦截器,springmvc框架将配置的类似全局的拦截器注入到每个HandlerMapping中。
<!--拦截器 -->
<mvc:interceptors>
<!--多个拦截器,顺序执行 -->
<mvc:interceptor>
<!-- /**表示所有url包括子url路径 -->
<mvc:mapping path="/**"/>
<bean class="com.huan.web.Interceptor1.Interceptor1"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.huan.web.Interceptor1.Interceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>
三.多拦截器测试
拦截器一:Interceptor1.java
package com.huan.web.Interceptor1;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Interceptor1 implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("拦截器一执行------preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器一执行-------postHandle");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("拦截器一执行------afterCompletion");
}
}
拦截器二:Interceptor2.java
package com.huan.web.Interceptor1;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Interceptor2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("拦截器二执行------preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("拦截器二执行-------postHandle");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("拦截器二执行------afterCompletion");
}
}
- 两个拦截器的preHandle都返回true
结论:preHandle按照顺序执行,postHandle、afterCompletion按照逆向顺序执行
- 拦截器一放行,拦截器二不放行
总结:
拦截器1放行,拦截器2 preHandle才会执行。
拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。
只要有一个拦截器不放行,postHandle不会执行。
- 拦截器一不放行,拦截器二放行
总结:
拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。
拦截器1 preHandle不放行,拦截器2不执行。
- 拦截器一不放行,拦截器二不放行
总结:
拦截器1 preHandle不放行,postHandle和afterCompletion不会执行。
拦截器1 preHandle不放行,拦截器2不执行。
文集:SpringMVC框架学习