SpringBoot学习要点记录(六)----拦截器

一、使用步骤

1.定义拦截器实现 Handlerlnterceptor接口;重写3个具体的拦截器方法。

public class MyInterceptor1 implements HandlerInterceptor {
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
							 Object handler) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器前方法");
		// 返回true,不会拦截后续的处理
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, 
						   Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器后方法");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, 
								Object handler, Exception ex) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器完成方法");
	}
}

2.注册拦截器

@Configuration
public class WebAppConfig implements WebMvcConfigurer {

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
	// 注册拦截器到Spring MVC机制,然后它会返回一个拦截器注册
	InterceptorRegistration ir = registry.addInterceptor(new MyInterceptor1());
	// 指定拦截匹配模式,限制拦截器拦截请求
	ir.addPathPatterns("/test/*");
	}
}

测试
测试Controller,这里没有配置页面,就简单测试了一下请求json数据的。

@RestController
@RequestMapping("/test")
public class TestController {
	@RequestMapping(value = "/json",method = RequestMethod.GET)
	public String test(){
		System.out.println("执行处理器逻辑");
		return "success";
	}
}

访问路径:http://localhost:8080/test/json
打印结果:

【MyInterceptor1】处理器前方法
执行处理器逻辑
【MyInterceptor1】处理器后方法
【MyInterceptor1】处理器完成方法

二、流程分析

  1. 执行preHandle方法
  2. 放行–执行处理器逻辑
  3. 执行postHandle方法
  4. 视图解析渲染
  5. 执行afterCompletion方法

三、多拦截器执行顺序

原则:处理器前方法采用先注册先执行,处理器后方法和完成
方法则是先注册后执行的规则
测试
配置第2个和第3个拦截器
MyInterceptor2

public class MyInterceptor2 implements HandlerInterceptor {
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
							 Object handler) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器前方法");
		// 返回true,不会拦截后续的处理
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response,
						   Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器后方法");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
								Object handler, Exception ex) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器完成方法");
	}
}

MyInterceptor3

public class MyInterceptor3 implements HandlerInterceptor {
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
							 Object handler) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器前方法");
		// 返回true,不会拦截后续的处理
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response,
						   Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器后方法");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
								Object handler, Exception ex) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器完成方法");
	}
}

注册拦截器2、3:

@Configuration
public class WebAppConfig implements WebMvcConfigurer {

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 注册拦截器到Spring MVC机制,然后它会返回一个拦截器注册
		InterceptorRegistration ir = registry.addInterceptor(new MyInterceptor1());
		// 指定拦截匹配模式,限制拦截器拦截请求
		ir.addPathPatterns("/test/*");

		//注册拦截器2
		InterceptorRegistration ir2 = registry.addInterceptor(new MyInterceptor2());
		ir2.addPathPatterns("/test/*");
		//注册拦截器3
		InterceptorRegistration ir3 = registry.addInterceptor(new MyInterceptor3());
		ir3.addPathPatterns("/test/*");
	}
}

执行结果

【MyInterceptor1】处理器前方法
【MyInterceptor2】处理器前方法
【MyInterceptor3】处理器前方法
执行处理器逻辑
【MyInterceptor3】处理器后方法
【MyInterceptor2】处理器后方法
【MyInterceptor1】处理器后方法
【MyInterceptor3】处理器完成方法
【MyInterceptor2】处理器完成方法
【MyInterceptor1】处理器完成方法

注意:拦截规则是一样的,同一个请求url会被这三个拦截器都拦截。
补充:拦截不通过的情况
这里假设第二个拦截器,没有放行。将MyInterceptor2 的preHandle方法返回值改为true,模拟不通过的情况。
修改MyInterceptor2 代码:

public class MyInterceptor2 implements HandlerInterceptor {
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
							 Object handler) throws Exception {
		System.out.println("【" + this.getClass().getSimpleName() +"】处理器前方法");
		// 返回false,拦截请求
		return fasle;
	}
	...
}

测试结果

【MyInterceptor1】处理器前方法
【MyInterceptor2】处理器前方法
【MyInterceptor1】处理器完成方法

分析:处理器前( preHandle )方法会执行,但是一旦返回 false ,则后续的拦截器、 处理器和所有拦截器的处理器后( postHandle ) 方法都不会被执行。完成方法 afterCompletion则不一样,它只会执行返回 true 的拦截器的完成方法,而且顺序是先注册后执行 。

发布了25 篇原创文章 · 获赞 2 · 访问量 840

猜你喜欢

转载自blog.csdn.net/Laputa219/article/details/103823754
今日推荐