详述SpringMVC中Interceptor拦截器

目录

一、自定义拦截器类

二、配置拦截器

三、执行顺序

1.preHandle

2.postHandle

3.afterCompletion 


一、自定义拦截器类

首先创建如下项目:

在web.xml中配置DispatchServlet:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>springsun</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

	<servlet>
		<servlet-name>DispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:application.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>DispatcherServlet</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
</web-app>

在Controller容器中创建拦截/userinfo/toView.do请求的Handler方法:

package club.affengkuang.userinfo;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UserInfoController {
	
	@RequestMapping("/userinfo/toView.do")
	public String toView() {
		System.out.println("toView......");
		return "to";
	}
}

接下来自定义拦截器:

创建AccessInterceptor类,实现HandlerInterceptor接口,并重写接口中的三个抽象方法preHandle、postHandle、afterCompletion,拦截器便自定义完成:

package club.affengkuang.interceptor;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

//创建一个HandlerInterceptor接口实现类
public class AccessInterceptor implements HandlerInterceptor {
	
	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
		System.out.println("preHandle......");
		return true;
	}
		
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		System.out.println("postHandle......");
	}

	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		System.out.println("afterCompletion......");
	}
}

二、配置拦截器

在application中配置15到17行mvc:interceptors标签内配置刚才自定义好的AccessInterceptor类:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<context:component-scan base-package="club.affengkuang"></context:component-scan>
	
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/view/" p:suffix=".jsp"></bean>
	
	<mvc:interceptors>
		<bean class="club.affengkuang.interceptor.AccessInterceptor"></bean>
	</mvc:interceptors>
</beans>

测试:

三、执行顺序

在请求处理过程中,拦截器中三个方法的执行顺序如下:

1.preHandle

preHandle方法在目标方法(Handler方法)执行前执行,一般用于校验,以下是底层代码分析:

请求处理执行过程见博客:SpringMVC中servlet请求处理过程

当使用debug方式,执行到DispatchServlet类中doDispatch方法时:

第962行:进入applyPreHandle方法

进入applyPreHandle后:

第129行:创建一个上转型对象数组,将所有拦截器对象赋值到父类接口的数组变量中,其中[1]中便是我们自定义的Accessinterceptor类对象

第131行:遍历interceptors中每个元素

第133行:此处使用多态,表层调用的是接口中preHandle方法,实则调用的是上转型对象重写的preHandle方法,也就是我们实现的preHandle方法; 

注意:在preHandle方法中返回值为Boolean类型

①假设该方法返回false时,该行if语句为true,执行if代码块

第135行:applyPreHandle方法返回false

上面的doDispatch方法中也直接结束执行,所以执行结果中只有preHandle方法被执行了:

②假设该方法返回true时,该行if语句为true,执行第140行语句,返回true:

回到doDispatch方法:

第967行:handle方法处理servlet中请求

2.postHandle

接着上面的源码分析:

进入第974行代码中的applyPostHandle方法:执行原理与preHandle方法相同,只不过在第151行执行的是在AccessInterceptor类中实现的postHandle方法:

3.afterCompletion 

随后执行到第984行,进入processDispatchResult方法:

然后执行到processDispatchResult方法中:

第1027行:如果此时没发生异常,exception为null,则不执行此代码;

第1059行:执行triggerAfterCompletion方法; 

执行原理与前面两个方法原理相同,此处169行执行的是在AccessInterceptor类中实现的afterCompletion方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值