天天看点

SpringMVC拦截器-Interceptor前言

前言

Spring MVC属于SpringFrameWork中的一个模块,也就是Spring实现WEB、实现MVC

而 Interceptor拦截器 是属于SpringMVC中的机制,作用是对于  Controller层接口执行前后 进行拦截,表现形式有点像Spring的AOP,但是AOP是针对单一的方法。Interceptor是针对Controller接口以及可以处理request和response对象。

1.HandlerInterceptor拦截器接口的定义

在该接口中,定义了一下三个方法

public interface HandlerInterceptor {
 
    boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
 
    void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;
 
    void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
           
  • preHandle:                                                                                                                                                                                  在访问到达Controller之前执行,如果需要对请求做预处理,可以选择在该方法中完成

    返回值为true:继续执行后面的拦截器或者Controller

    返回值为false:不再执行后面的拦截器和Controller,并调用返回true的拦截器的afterCompletion方法                                                ( 多个拦截器拦截时,先声明的先调用)

  • postHandle:    

    在执行完Controller方法之后,DispatcherServlet渲染视图之前执行,如果需要对响应相关的数据进行处理,可以选择在该方法中完成,(多个拦截器时)先声明的后调用。

  • afterCompletion:                                                                                                                                                                       调用完Controller接口,渲染View页面后调用。返回true的拦截器都会调用该拦截器的afterCompletion方法。                       (多个拦截器时) 先声明的后调用。只要有一个拦截器的preHandle 为true,那么它的 afterCompletion 方法就一定会执行。    

2.流程图:

SpringMVC拦截器-Interceptor前言

3.自定义拦截器 以及使用

1. 定义拦截器,首先我们要定义一个类,实现HandlerInterceptor接口,重写对应的方法

public class MyFirstInterceptor implements HandlerInterceptor {

	/**
         * 	在控制器执行之前进行拦截操作
         *	方法的返回值 为 true 控制器方法放行 ,如果返回false则不放行
         */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("MyFirstInterceptor.......preHandle执行了");
		
		return true;  
	}

	/**
	 * 	在Controller方法调用之后执行,但是它会在DispatcherServlet进行视图返回渲染之前被调用
         */
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("MyFirstInterceptor.......postHandle执行了");
	}

	/**
         *	 在完成视图渲染之后,执行此方法。
	 */
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("MyFirstInterceptor.......afterCompletion执行了");
	}
}

           

2.在SpringMVC 配置文件中配置 拦截器

<!-- 添加拦截器 -->
<mvc:interceptors>
   
   <!-- 配置具体的拦截器,如果不指定拦截具体请求,默认拦截所有 -->
   <bean class="com.crud.interceptor.MyFirstInterceptor"></bean>
   
   <!-- 配置具体的拦截器
    <mvc:interceptor>
    	配置要拦截的目标方法
    	<mvc:mapping path="interceptor/handler01"/>
    	<bean class="com.crud.interceptor.MyFirstInterceptor"></bean>
    </mvc:interceptor> -->   		
   
 </mvc:interceptors>
           

3.Controller

@RequestMapping("/handler01")
public String handler01(Model mod) {
		
	System.out.println("目标方法执行............");		
		
	mod.addAttribute("message", "访问成功");
	return "success";
}
           

4.index.jsp 页面

<a href="interceptor/handler01" target="_blank" rel="external nofollow" >发送请求,进入拦截器</a>
           

5.访问成功页面

<body>
	<h1>${message}</h1>
	<% System.out.println("访问了 success.jsp....");%>
</body>
           

访问演示:

客户端登录index.jsp 页面,点击超链接(请求被拦截器拦截) 

     查看控制器台输出:

        MyFirstInterceptor.......preHandle执行了

        目标方法执行............

        MyFirstInterceptor.......postHandle执行了

        访问了 success.jsp....

        MyFirstInterceptor.......afterCompletion执行了

以上是正常的执行顺序,还有其他情况下的执行顺序

    执行顺序: 

        正常执行过程

        preHandle --> 目标方法 --> postHandle --> 目标页面 --> afterCompletion

        当preHandle返回false,不放行Controller时

        preHandle  执行了

        当目标方法出现异常时,执行过程

        preHandle --> 目标方法 --> afterCompletion

4.多个拦截器时,执行顺序

代码如上 3.0 ,我们再编写一个拦截器。

public class MyTowInterceptor  implements HandlerInterceptor{

	//执行Controller 之前拦截
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("MyTowInterceptor.....preHandle...执行了");
		return true;
	}
	//执行完目标方法后 视图渲染前执行
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("MyTowInterceptor.....postHandle...执行了");
	}

	// 渲染完视图 之后执行
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("MyTowInterceptor.....afterCompletion...执行了");
	}

}
           

在SpringMVC配置文件中,配置拦截器

<!-- 添加拦截器 -->
   <mvc:interceptors>
   
   	<!-- 配置具体的拦截器,如果不指定拦截具体请求,默认拦截所有 -->

    <!-- 配置拦截器 -->
   	<bean class="com.crud.interceptor.MyFirstInterceptor"></bean>
    <!-- 配置拦截器 -->
    <bean class="com.crud.interceptor.MyTowInterceptor"></bean>

</mvc:interceptors>
           

浏览器访问: http:localhost:8080.../index.jsp

SpringMVC拦截器-Interceptor前言

点击超链接,发送请求

SpringMVC拦截器-Interceptor前言

查看控制台输出:

MyFirstInterceptor.......preHandle执行了

MyTowInterceptor.....preHandle...执行了

目标方法执行............

MyTowInterceptor.....postHandle...执行了

MyFirstInterceptor.......postHandle执行了

访问了 success.jsp....

MyTowInterceptor.....afterCompletion...执行了

MyFirstInterceptor.......afterCompletion执行了

我们来看它的执行顺序

1. 首先是两个拦截器的 preHandle 方法  按照先后声明顺序   执行了,

2. 然后执行Controller方法

3. 执行完Controller方法后,在前端控制器渲染视图前,执行了postHandle 方法

                  postHandle方法按照逆序执行,先声明的后执行

4. 然后jsp 视图页面被渲染完成了

5. 视图渲染完之后,执行了afterCompletion 方法。该方法也是逆序执行,先声明的后执行

若此时第一个拦截器( MyFirstInterceptor) 的preHandle方法返回false,会怎样,让执行看看顺序

控制台输出:

MyFirstInterceptor.......preHandle执行了

此时第一个拦截器的preHandle方法返回false之后,请求就中断了,后边的拦截器Controller也不会执行了

如果目标方法发生异常时,执行顺序又是什么请求呢? 

控制台输出:

MyFirstInterceptor.......preHandle执行了

MyTowInterceptor.....preHandle...执行了

目标方法执行............

MyTowInterceptor.....afterCompletion...执行了

MyFirstInterceptor.......afterCompletion执行了

1. 两个过滤器的preHandle都执行了

2. 到目标方法后发生异常

3. 然后按照逆序执行返回true的拦截器的afterCompletion方法 

5.拦截器与过滤器的区别

过滤器是 javaEE三大核心技术之一  (servlet的规范) ,初始化由容器创建

拦截器是属于SpringMVC的,只有在SpringMVC 中才能使用拦截器,由SpringIOC创建

部分转载自:

https://blog.csdn.net/wolfcode_cn/article/details/82965064

https://blog.csdn.net/weixin_42594325/article/details/80909946