它主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。
实现拦截器的两种方式:
通过实现 HandlerInterceptor 接口或继承 HandlerInterceptor 接口的实现类来定义
通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。
下面是实现 HandlerInterceptor 接口的方式:
1、定义一个BaseController
package com.woo.controller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.bind.annotation.ModelAttribute;
public abstract class BaseController {
private static final Log logger = LogFactory.getLog(BaseController.class);
@ModelAttribute
public void checkUser(){
System.out.println("baseController---checkUser");
}
}
2、写一个WooController
package com.woo.controller;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class WooController extends BaseController{
private static final Log logger = LogFactory.getLog(WooController.class);
@RequestMapping(value = "/woo")
public String woo(){
System.out.println("woo---");
return "woo";
}
@RequestMapping(value = "/register")
@ResponseBody
public String register() {
System.out.println("register---");
return "success";
}
}
注:因为BaseController中 checkUser 方法 使用了 @ModelAttribute 注解,所以在执行 BaseController 的子类方法时,都会先调用 checkUser;
3、写一个拦截器,实现 HandlerInterceptor 接口
package com.woo.HandlerInterceptor;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
System.out.println("postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
System.out.println("afterCompletion方法在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行");
}
}
preHandle 方法 返回 true 表示继续向下执行,返回 false 表示中断后续操作。
4、配置applicationContext.xml 文件
<!--配置拦截器-->
<mvn:interceptors>
<mvc:interceptor>
<!-- 配置拦截器作用的路径 -->
<mvc:mapping path="/**" />
<!-- 配置不需要拦截作用的路径 -->
<mvc:exclude-mapping path="/register" />
<!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
<bean class="com.woo.HandlerInterceptor.MyHandlerInterceptor" />
</mvc:interceptor>
</mvn:interceptors>
此处,WooController 中的 register 方法不被拦截,其余方法都将拦截:
5、测试:
http://localhost:8080/spring_mvc_pro/woo
http://localhost:8080/spring_mvc_pro/register
当把拦截器MyHandlerInterceptor的preHandle方法返回值改为true 时:
http://localhost:8080/spring_mvc_pro/woo
http://localhost:8080/spring_mvc_pro/register
总结:
如果A方法被拦截:先执行的是拦截器方法,通过后,执行的BaseController 的 @ModelAttribute 方法。执行A方法
如果A方法不被拦截:则不执行拦截器方法,执行BaseController 的 @ModelAttribute 方法。执行A方法
多拦截器时,拦截器执行顺序: