十一、拦截器
1、拦截器的配置
SpringMVC中的拦截器用于拦截控制器方法的执行
SpringMVC中的拦截器需要实现HandlerInterceptor或者继承HandlerInterceptorAdapter类
开启mvc注解驱动,并设置处理响应中文乱码
<!--开启MVC的注解驱动 开启注解驱动后,由于view-controller导致的原来在控制器中的所有请求映射 全部重新有效。 --> <mvc:annotation-driven> <mvc:message-converters> <!--处理响应中文内容乱码--> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="defaultCharset" value="UTF-8" /> <property name="supportedMediaTypes"> <list> <value>text/html</value> <value>application/json</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
实现步骤:
1)在src/main/java/com/atguigu/mvc包下创建interceptors包,用于存放拦截器。然后在interceptors包下创建FirstInterceptor类作为第一个拦截器。想要使用拦截器中的三个方法还需要让FirstInterceptor实现HandlerInterceptor的接口,然后重写方法(快捷键ctrl+O):
//@Component:将FirstInterceptor交由IOC容器管理 @Component public class FirstInterceptor implements HandlerInterceptor { //preHandle:在控制器方法执行之前执行 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("FirstInterceptor-->preHandle"); //返回false表示拦截,返回true表示放行 return true; } //postHandle:在控制器方法执行之后执行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("FirstInterceptor-->postHandle"); } //afterCompletion:在渲染视图完毕后执行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("FirstInterceptor-->afterCompletion"); } }
2)将FirstInterceptor交由IOC容器管理后,需要将其在springMVC.xml中配置扫描组件:
<!--自动扫描包--> <context:component-scan base-package="com.atguigu.mvc.interceptors" />
或者直接扫描controller包和interceptors包的上一层包(mvc包):
<!--自动扫描包--> <context:component-scan base-package="com.atguigu.mvc" />
3)SpringMVC的拦截器想要起作用就必须在SpringMVC的配置文件中进行配置,拦截器的配置方法有三种。
-
配置方法一
使用该方法时不需要将FirstInterceptor类放入IOC容器管理:
<!--配置拦截器--> <mvc:interceptors> <bean class="com.atguigu.mvc.interceptors.FirstInterceptor" /> </mvc:interceptors>
-
配置方法二
也可以这样写,效果都一样,不过使用该方法时需要将FirstInterceptor类放入IOC容器管理:
<!--配置拦截器--> <mvc:interceptors> <ref bean="firstInterceptor" /> </mvc:interceptors>
以上两种配置都是对DispatcherServlet所处理的所有请求进行拦截。
-
配置方法三
该方法可以设置和排除需要拦截的路径
<!--配置拦截器--> <mvc:interceptors> <mvc:interceptor> <!--'mvc:mapping'设置需要拦截的请求。'/*'表示拦截所有请求--> <mvc:mapping path="/*"/> <!--'mvc:exclude-mapping'设置需要排除拦截的请求。'/'表示访问斜线时不会被拦截--> <mvc:exclude-mapping path="/"/> <!--指定拦截器--> <ref bean="firstInterceptor" /> </mvc:interceptor> </mvc:interceptors>
2、拦截器的三个抽象方法
SpringMVC中的拦截器有三个抽象方法:
preHandle:控制器方法执行之前执行preHandle,其boolean类型的返回值表示是否拦截或放行,返回true为放行,即调用控制器方法:返回false表示拦截,即不调用控制器方法。
postHandle:控制器方法执行之后执行postHandle()
afterComplation:处理完视图和摸型数据,渲染视图完毕之后执行afterComplation()
//preHandle:在控制器方法执行之前执行 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //返回false表示拦截,返回true表示放行 return false; } //postHandle:在控制器方法执行之后执行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } //afterCompletion:在渲染视图完毕后执行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
3、多个拦截器的执行顺序
a>若每个拦截器的preHandle()都返回true
此时多个拦截器的执行顺序和拦截器在SpringMVC的配置文件的配置顺序有关:
preHandle()会按照配置的顺序执行,而postHandle()和afterComplation()会按照配置的反序执行
b>若某个拦截器的preHandle()返回了false
preHandle()返回false和它之前的拦截器的preHandle()都会执行,postHandle()都不执行,返回false的拦载器之前的拦截器的afterComplation()会执行
实现步骤:
1)在interceptors包下新建SecondInterceptor类,作为第二个拦截器
//@Component:将FirstInterceptor交由IOC容器管理 @Component public class SecondInterceptor implements HandlerInterceptor { //preHandle:在控制器方法执行之前执行 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("SecondInterceptor-->preHandle"); //返回false表示拦截,返回true表示放行 return true; } //postHandle:在控制器方法执行之后执行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("SecondInterceptor-->postHandle"); } //afterCompletion:在渲染视图完毕后执行 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("SecondInterceptor-->afterCompletion"); } }
springMVC.xml中设置为
<!--配置拦截器--> <mvc:interceptors> <ref bean="firstInterceptor" /> <ref bean="secondInterceptor" /> </mvc:interceptors>
输出为:
FirstInterceptor-->preHandle SecondInterceptor-->preHandle SecondInterceptor-->postHandle FirstInterceptor-->postHandle SecondInterceptor-->afterCompletion FirstInterceptor-->afterCompletion