12 拦截器

12.1拦截器概述

Spring MVC 的拦截器(Interceptor)与 Java Servlet 的过滤器(Filter)类似,它主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。

12.1.1拦截器的定义

在 Spring MVC 框架中定义一个拦截器需要对拦截器进行定义和配置,定义一个拦截器可以通过两种方式:一种是通过实现 HandlerInterceptor 接口或继承 HandlerInterceptor 接口的实现类来定义;另一种是通过实现 WebRequestInterceptor 接口或继承 WebRequestInterceptor 接口的实现类来定义。

public class TestInterceptor implements HandlerInterceptor {
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("afterCompletion方法在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行");
    }
    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
    }
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
        return false;
    }

在上述拦截器的定义中实现了 HandlerInterceptor 接口,并实现了接口中的 3 个方法。有关这 3 个方法的描述如下。

  • preHandle 方法:该方法在控制器的处理请求方法前执行,其返回值表示是否中断后续操作,返回 true 表示继续向下执行,返回false 表示中断后续操作。
  • postHandle方法:该方法在控制器的处理请求方法调用之后、解析视图之前执行,可以通过此方法对请求域中的模型和视图做进一步的修改。
  • afterCompletion方法:该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行,可以通过此方法实现一些资源清理、记录日志信息等工作。

12.1.2拦截器的配置

让自定义的拦截器生效需要在 Spring MVC 的配置文件中进行配置,配置示例代码如下:

<!-- 配置拦截器 -->
<mvc:interceptors>
    <!-- 配置一个全局拦截器,拦截所有请求 -->
    <bean class="interceptor.TestInterceptor" /> 
    <mvc:interceptor>
        <!-- 配置拦截器作用的路径 -->
        <mvc:mapping path="/**" />
        <!-- 配置不需要拦截作用的路径 -->
        <mvc:exclude-mapping path="" />
        <!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
        <bean class="interceptor.Interceptor1" />
    </mvc:interceptor>
    <mvc:interceptor>
        <!-- 配置拦截器作用的路径 -->
        <mvc:mapping path="/gotoTest" />
        <!-- 定义在<mvc: interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
        <bean class="interceptor.Interceptor2" />
    </mvc:interceptor>
</mvc:interceptors>

<mvc:interceptors> 元素用于配置一组拦截器,其子元素 bean 定义的是全局拦截器,即拦截所有的请求。

<mvc:interceptor> 元素中定义的是指定路径的拦截器,其子元素 <mvc:mapping> 用于配置拦截器作用的路径,该路径在其属性 path 中定义。

如上述示例代码中,path 的属性值“/**”表示拦截所有路径,“/gotoTest”表示拦截所有以“/gotoTest”结尾的路径。如果在请求路径中包含不需要拦截的内容,可以通过 <mvc:exclude-mapping> 子元素进行配置。

需要注意的是,<mvc:interceptor> 元素的子元素必须按照 <mvc:mapping.../>、<mvc:exclude-mapping.../>、<bean.../> 的顺序配置。

12.2拦截器的执行流程

12.2.1单个拦截器的执行流程.

1)创建应用并将 Spring MVC 相关的 JAR 包复制到 lib 目录中。
2)创建 web.xml
3)创建控制器类

@Controller
public class HelloController {
	/**
	 * 页面跳转
	 */
	@RequestMapping("/hello")
	public String Hello() {
         System.out.println("Hello!");
	    return "success";
	}
}

4)创建拦截器类

public class CustomInterceptor implements HandlerInterceptor{
	@Override
	public boolean preHandle(HttpServletRequest request, 
		HttpServletResponse response, Object handler)throws Exception {
		System.out.println("CustomInterceptor...preHandle");
         //对拦截的请求进行放行处理 
		return true;
	}
	@Override
	public void postHandle(HttpServletRequest request, 
		HttpServletResponse response, Object handler, 
		ModelAndView modelAndView) throws Exception {
		System.out.println("CustomInterceptor...postHandle");
	}
	@Override
	public void afterCompletion(HttpServletRequest request, 
		HttpServletResponse response, Object handler, 
		Exception ex) throws Exception {		
		System.out.println("CustomInterceptor...afterCompletion");
	}
}

5)创建配置文件 springmvc-servlet.xml

<bean class="com.itheima.interceptor.CustomInterceptor"/>

6)测试拦截器
通过地址http://localhost:8080/vacation_13_0222/hello测试拦截器。程序正确执行后控制
在这里插入图片描述

12.2.2多个拦截器的执行流程

此时需要编写多个拦截器类,并且都在配置文件中声明
运行结果为
在这里插入图片描述
可以看出当有多个拦截器同时工作时,它们的 preHandler方法按照配置文件中拦截器的 配置顺序执行,而它们的postHandler方法和afterComplrtion方法则会按照配置顺序的反序执行。

posted @ 2021-02-20 21:44  我就是隔壁老张  阅读(75)  评论(0编辑  收藏  举报