欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring MVC 学习笔记 7《拦截器(Interceptor)》

程序员文章站 2022-05-23 10:34:11
...


上一篇,我们在处理异常后跳转控制时使用了拦截器那这篇就来详细梳理一下相关知识点

SpringMVC 拦截器(Interceptor)和 过滤器(Filter)的执行顺序

DispactherServlet–>拦截器–>preHandle–>单元方法—>postHandle—>jsp资源—>afterCompletion–>DispactherServlet

过滤器(Filter)

Filter_1
Filter_2
Filter_3
DispactherServlet

过滤器在Servlet之前,范围比较大,用于处理全局性的问题。比如编码设置。详细看这里 Servlet 编写过滤器

拦截器(Interceptor)

可以对一个控制器方法定义多个拦截器
/ssm/src/main/java/com/jerry/ssm/interceptor/AllInterceptor.java

package com.jerry.ssm.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.apache.tomcat.util.http.fileupload.servlet.ServletRequestContext;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class AllInterceptor implements HandlerInterceptor {
	
	/**
	 * 拦截在控制方法之前,对数据进行预处理。可以通过返回{@code true}和{@code false}控制是打断请求还是继续。继续则调用下一个拦截器的`preHandle`如果没有了就调`控制方法`
	 * @param request 本次 HTTP 请求对象
	 * @param response 本次 HTTP 相应对象
	 * @param handler HandleMethod类型,该参数的实参中封存了此次请求要调用的控制方法的Method对象。 有需要可以调用它。
	 * @return {@code true}:放行,继续执行控制器方法,否则拦截此次请求不再继续执行控制器方法
	 * @throws Exception
	 */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    	System.out.println(this.getClass().getSimpleName()  + "#preHandle");
        return true;
    }
 
	/**
	 * 在控制方法之后,视图渲染之前执行。可以对控制方法返回的数据进行加工处理
	 * @param request 本次 HTTP 请求对象
	 * @param response 本次 HTTP 相应对象
	 * @param handler HandleMethod类型,该参数的实参中封存了此次请求要调用的控制方法的Method对象。 有需要可以调用它。
	 * @param modelAndView ModelAndView类型,控制方法返回的数据都在这里面。
	 * @throws Exception
	 */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    	System.out.println(this.getClass().getSimpleName()  + "#postHandle");
    }
 
    
	/**
	 * 最后执行,处理前面方法的异常
	 * @param request 本次 HTTP 请求对象
	 * @param response 本次 HTTP 相应对象
	 * @param handler HandleMethod类型,该参数的实参中封存了此次请求要调用的控制方法的Method对象。 有需要可以调用它。
	 * @param ex Exception类型
	 * @throws Exception
	 */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    	System.out.println(this.getClass().getSimpleName()  + "#afterCompletion");
    }
}

Test_1到4_Interceptor 同上

spring-mvc.xml

/ssm/src/main/resources/spring-mvc.xml

    <!-- =========================== 配置拦截器 =========================== -->
	<mvc:interceptors>  
	    <!-- 全局拦截器:使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->  
		<bean class="com.jerry.ssm.interceptor.AllInterceptor"/>
		
	    <!-- 局部拦截:mvc:interceptor 可以配置多个,bean对象只会拦截指定的单元方法 -->
		<mvc:interceptor>
			<!-- 配置拦截范围,可多个 -->
		    <mvc:mapping path="/"/>
	    	<mvc:mapping path="/test1"/>
	    	<!-- 定义在 mvc:interceptor 下面的表示是对特定的请求才进行拦截的 -->  
	    	<bean class="com.jerry.ssm.interceptor.Test_1_Interceptor"/>
		</mvc:interceptor>  
		
		<mvc:interceptor>
		  	<mvc:mapping path="/"/> <!-- web项目的根目录 -->
	    	<bean class="com.jerry.ssm.interceptor.Test_2_Interceptor"/>
		</mvc:interceptor>  
		
		<mvc:interceptor>
		    <mvc:mapping path="/*"/> <!-- 所有文件夹,不含子文件夹 -->
	    	<bean class="com.jerry.ssm.interceptor.Test_3_Interceptor"/>
		</mvc:interceptor>  
		
		<mvc:interceptor>
		    <mvc:mapping path="/**"/> <!-- 所有文件夹及里面的子文件夹 -->
	    	<bean class="com.jerry.ssm.interceptor.Test_4_Interceptor"/>
		</mvc:interceptor>  
	     
	</mvc:interceptors> 
DispactherServlet postHandle preHandle
4
3
2
1
4
3
2
1
1
2
3
4
DispactherServlet
控制方法
DispactherServlet
AllInterceptor#preHandle
	Test_1_Interceptor#preHandle
		Test_2_Interceptor#preHandle
			Test_3_Interceptor#preHandle
				Test_4_Interceptor#preHandle
				
					http://localhost 控制方法
				
				Test_4_Interceptor#postHandle
			Test_3_Interceptor#postHandle
		Test_2_Interceptor#postHandle
	Test_1_Interceptor#postHandle
AllInterceptor#postHandle

Test_4_Interceptor#afterCompletion
Test_3_Interceptor#afterCompletion
Test_2_Interceptor#afterCompletion
Test_1_Interceptor#afterCompletion
AllInterceptor#afterCompletion