编程知识 cdmana.com

SpringMVC 拦截器使用方法 SpringMVC拦截器执行顺序理解

           SpringMVC 拦截器使用方法 SpringMVC拦截器执行顺序理解

 

一、拦截器作用

1、Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。

 

二、使用方法

1、依赖 spring-webmvc

 <dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-webmvc</artifactId>
	    <version>4.3.20.RELEASE</version>
     </dependency>

 

2、创建一个LogInterceptor 类,实现 org.springframework.web.servlet.HandlerInterceptor 接口

 

3、重写的 preHandle 、 postHandle 、 afterCompletion 作用如下

 /**
	 * preHandle: Controller 执行之前,调用该方法
	 * 返回 true,表示继续执行 ; 返回 false ,终止执行。
	 * 应用: 登陆校验、权限拦截 等。
	 */
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		System.out.println("LogInterceptor =====> preHandle ");
		return true;
	}
	
	/**
	 * postHandle: Controller 执行之后,但未返回视图前,调用此方法。
	 * 应用:对模型数据进行加工处理,加入公用信息以便页面显示 ; 或者手机、平板等移动端访问,返回对应页面数据。
	 */
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView view)
			throws Exception {
		System.out.println("LogInterceptor =====> postHandle ");
		if(null != view) {
			System.out.println("viewName: "+view.getViewName());
		}
		
	}
	
	/**
	 * afterCompletion: Controller 执行之后,且返回视图后,调用此方法。
	 * 应用:日志记录、异常记录、资源清理等。
	 */
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("LogInterceptor =====> afterCompletion ");
	}

 

4、spirng-mvc.xml 中配置拦截器

<mvc:interceptors>
    <!-- LogInterceptor  -->
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean id="logInterceptor" class="com.runcode.interceptor.LogInterceptor" />
    </mvc:interceptor>
  </mvc:interceptors>

 

5、启动项目,请求任意一个url,可以看到控台输出:

LogInterceptor =====> preHandle  //  执行Controller 之前
hello  // 执行Controller
LogInterceptor =====> postHandle // 执行Controller,返回视图之前 
LogInterceptor =====> afterCompletion // 执行Controller,返回视图之后

 

三、执行顺序理解

1、分别创建 FirstInterceptor 和 SecondInterceptor  (源码这里

public class FirstInterceptor implements HandlerInterceptor {
	
	@Override
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		System.out.println("FirstInterceptor  ---> preHandle" );
		return true;
	}
	
	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("FirstInterceptor  ---> postHandle" );
	}
	
	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("FirstInterceptor  ---> afterCompletion" );
	}
}

 

2、FirstInterceptor 和 SecondInterceptor 顺序 配置如下(先First,后Second):

<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/userController/**"/>
			<bean class="com.runcode.interceptor.FirstInterceptor" />
		</mvc:interceptor>
		<mvc:interceptor>
			<mvc:mapping path="/userController/**"/>
			<bean class="com.runcode.interceptor.SecondInterceptor" />
		</mvc:interceptor>
	</mvc:interceptors>

3、FirstInterceptor 和 SecondInterceptor 的 preHandle 方法都返回 true

4、控制台输出如下:

FirstInterceptor  ---> preHandle
SecondInterceptor  ---> preHandle
SecondInterceptor  ---> postHandle
FirstInterceptor  ---> postHandle
SecondInterceptor  ---> afterCompletion
FirstInterceptor  ---> afterCompletion

 

5、SecondInterceptor 和 FirstInterceptor 倒序 配置如下(先Second,后First)

<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/userController/**"/>
			<bean class="com.runcode.interceptor.SecondInterceptor" />
		</mvc:interceptor>
		<mvc:interceptor>
			<mvc:mapping path="/userController/**"/>
			<bean class="com.runcode.interceptor.FirstInterceptor" />
		</mvc:interceptor>
	</mvc:interceptors>

6、FirstInterceptor 和 SecondInterceptor 的 preHandle 方法都返回 true 。

7、控制台输出如下:

SecondInterceptor  ---> preHandle
FirstInterceptor  ---> preHandle
FirstInterceptor  ---> postHandle
SecondInterceptor  ---> postHandle
FirstInterceptor  ---> afterCompletion
SecondInterceptor  ---> afterCompletion

8、根据拦截器配置顺序,配置在前: preHandle 先执行; postHandle 和 afterCompletion,后执行。

 

四、返回false时测试

1、FirstInterceptor 和 SecondInterceptor 顺序配置,但FirstInterceptor 的 preHandle返回 false , SecondInterceptor 的preHandle返回 true 。 (先First,后Second , 配置 【三-2】)

2、控制台输出如下:

FirstInterceptor ---> preHandle

3、结论: SecondInterceptor 和 Controller 都不执行。

4、FirstInterceptor 和 SecondInterceptor 顺序配置,但FirstInterceptor的preHandle返回 true , SecondInterceptor 的preHandle返回 false 。(先First,后Second , 配置 【三-2】)

FirstInterceptor  ---> preHandle
SecondInterceptor  ---> preHandle
FirstInterceptor  ---> afterCompletion

5、结论:拦截器中只要有返回false,则 postHandle 方法不会执行 ; 单一拦截器中,preHandle 返回true, afterCompletion 才会执行。

 

五、总结

1、按照 springmvc.xml中配置的拦截器先后顺序,规律如下:

  • preHandle 按照顺序执行 (配置在前,先执行)

  • postHandle 按照倒序执行。 (配置在前,后执行)

  • afterCompletion 同 postHandle 。

 

2、多个拦截器中,只要有返回false,则 postHandle 方法不会执行。(全部返回true,postHandle 方法才执行)

3、多个拦截器中,只要有返回 false,则对应 Controller 也不会执行。

4、单一拦截器中,preHandle 返回true,则 afterCompletion 才会执行。

5、单一拦截器中,preHandle 返回 false,则 preHandle 和 afterCompletion 不会执行。

 

 

源码下载: https://gitee.com/RunCoder/spring-mvc-tourist/tree/interceptor

 

版权声明
本文为[HaHa_Sir]所创,转载请带上原文链接,感谢
https://thinkcode.blog.csdn.net/article/details/103901616

Scroll to Top