自定义拦截器的执行顺序

时间:2024-03-21 14:52:38

一、正常放行情况

1.第一个拦截器实现:

package springboot.example.interceptor;

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

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 自定义拦截器
 * @author lich
 *
 */
@Component
public class ApiInterceptor extends HandlerInterceptorAdapter {

	/**
	 * 请求之前:
	 * 	进入handler方法之前执行
	 * 	用户身份认证、身份授权
	 *  应用场景:比如身份认证,如认证通过表示当前用户没有登录,需要此方法拦截不再向下执行
	 */
	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
			throws Exception {
		System.out.println("进入拦截器1");
		//return false; 表示拦截,不再向下执行
		//return true;  表示放行
		return true;
	}

	/**
	 * 请求时:
	 * 	进入handler之后,返回modelAndView之前执行
	 *  应用场景:从modelAndView出发,将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
	 */
	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
			ModelAndView modelAndView) throws Exception {
		System.out.println("拦截1过程处理些事情……");
	}

	/**
	 * 请求完成:
	 * 	执行handler完成之后执行
	 *  应用场景:统一异常处理,统一日志处理
	 */
	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
			Object o, Exception e) throws Exception {
		System.out.println("拦截1完成");
	}

}

2.第二个拦截器的实现:

package springboot.example.interceptor;

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

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 自定义拦截器
 * @author lich
 *
 */
@Component
public class ApiInterceptor2 extends HandlerInterceptorAdapter {

	/**
	 * 请求之前:
	 * 	进入handler方法之前执行
	 * 	用户身份认证、身份授权
	 *  应用场景:比如身份认证,如认证通过表示当前用户没有登录,需要此方法拦截不再向下执行
	 */
	@Override
	public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
			throws Exception {
		System.out.println("进入拦截器2");
		//return false; 表示拦截,不再向下执行
		//return true;  表示放行
		return false;
	}

	/**
	 * 请求时:
	 * 	进入handler之后,返回modelAndView之前执行
	 *  应用场景:从modelAndView出发,将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图
	 */
	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
			ModelAndView modelAndView) throws Exception {
		System.out.println("拦截2过程处理些事情……");
	}

	/**
	 * 请求完成:
	 * 	执行handler完成之后执行
	 *  应用场景:统一异常处理,统一日志处理
	 */
	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
			Object o, Exception e) throws Exception {
		System.out.println("拦截2完成");
	}

}

3.这里采用springboot对拦截器进行注册:

/**
 * 注解配置类
 * @author lich
 *
 */
@SpringBootConfiguration
public class WebConfig extends WebMvcConfigurationSupport {
	
	/**
	 * 注册自定义拦截器
	 */
	@Override
	protected void addInterceptors(InterceptorRegistry registry) {
		super.addInterceptors(registry);
		registry.addInterceptor(new ApiInterceptor());
		registry.addInterceptor(new ApiInterceptor2());
	}
}

4.执行的顺序

自定义拦截器的执行顺序

在此可以知道拦截器的执行流程和springboot注册的顺序有关,以下是拦截器的正常流程的执行顺序

自定义拦截器的执行顺序

二、非正常情况(第一个放行,第二个拦截)

此处可以查看pre的返回类型,如果为true,则是放行,如果为false,则是拦截不放行。

再次启动所产生的日志

自定义拦截器的执行顺序

总结

拦截器1放行,拦截器2 preHandle才会执行。

拦截器2 preHandle不放行,拦截器2 postHandle和afterCompletion不会执行。

只要有一个拦截器不放行,postHandle不会执行。

 

参考博客:https://blog.csdn.net/u012401711/article/details/73741974

相关文章