Spring 学习总结笔记【十一、SpringMVC拦截器】

往期文章:

Spring 学习总结笔记【一、快速入门】
Spring 学习总结笔记【二、IoC-控制反转】
Spring 学习总结笔记【三、注解开发】
Spring 学习总结笔记【四、整合Junit】
Spring 学习总结笔记【五、配置数据源】
Spring 学习总结笔记【六、整合Mybatis】
Spring 学习总结笔记【七、AOP面向切面编程】
Spring 学习总结笔记【八、集成Web环境】
Spring 学习总结笔记【九、SpringMVC快速入门】
Spring 学习总结笔记【十、SpringMVC数据响应与请求】

一、拦截器概念

在系统中,经常需要在处理用户请求之前和之后执行一些行为,例如检测用户的权限,或者将请求的信息记录到日志中等等,所以需要一种机制,拦截用户的请求,在请求的前后添加处理逻辑。
Spring MVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。
将拦截器按一定的顺序联结成一条链,这条链称为拦截器链(InterceptorChain)。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。拦截器也是AOP思想的具体实现。

  • 拦截器(Interceptor):是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
  • 作用
    ① 在指定的方法调用前后执行预先设定的代码
    ② 阻止原始方法的执行

在这里插入图片描述

拦截器与过滤器区别:

  • 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
  • 拦截内容不同:Filter对所有访问进行增强,Interceptor仅针对SpringMVC的访问进行增强
    在这里插入图片描述

二、拦截器开发步骤

①创建拦截器类实现HandlerInterceptor接口

package com.tyt.controller.interceptor;

// 若基于注解开发,需要加 @Component 注解,否则不需要
@Component
public class ProjectInterceptor implements HandlerInterceptor {

	/**
	* 访问Controller某个方法之前执行
	* @param request 可以在方法请求进来之前更改request中的属性值
	* @param response
	* @param handler 封装了当前处理方法的信息,可对其进行反射操作
	* @return true 后续调用链是否执行; false 则中断后续执行
	* @throws Exception
	*/
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		System.out.println("preHandle...");
		// PreHandle方法若返回的false表示不放行,整个流程处于被拦截状态。
		return true;
	}
	
	/**
	* 视图被渲染之前(Controller方法调用之后)调用
	* preHandle方法处理之后这个方法会被调用,如果控制器Controller出现了异常,则不会执行此方法
	* @param request
	* @param response 可以在方法执行后去更改response中的信息
	* @param handler  封装了当前处理方法的信息
	* @param modelAndView 封装了model和view,所以当请求结束后可以修改model中的数据或者新增model数据,也可以修改view的跳转
	* @throws Exception9
	*/
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		System.out.println("postHandle...");
	}
	
	/**
	* 如果preHandle返回false则不会执行该方法
	* 在视图渲染之后执行,相当于try catch finally 中finally,出现异常也一定会执行该方法
	* @param request
	* @param response
	* @param handler
	* @param ex
	* @throws Exception
	*/
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		System.out.println("afterCompletion...");
	}
}
  • preHandle:预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
  • postHandle:后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。
  • afterCompletion:整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器才会执行。

在这里插入图片描述

② 配置拦截器

  • 基于XML配置

在Spring核心配置文件中配置拦截器

<!--  配置拦截器  -->
<mvc:interceptors>
	<mvc:interceptor>
		<!--  指定对哪些资源进行拦截操作  -->
		<mvc:mapping path="/**"/>
		<bean class="com.tyt.controller.interceptor"/>
	</mvc:interceptor>
</mvc:interceptors>

  • 基于注解开发
    有两种方法

方法① :可定义一个类继承WebMvcConfigurationSupport 类并注册拦截器,之后SpringMvc核心配置类配置包扫描至该类所在包。

package com.tyt.config;

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {

	@Autowired
	private ProjectInterceptor projectInterceptor;
	
	@Override
	protected void addInterceptors(InterceptorRegistry registry) {
		// 添加拦截器并设定拦截的访问路径,路劲可以通过可变参数设置多个
		registry.addInterceptor(projectInterceptor).addPathPatterns("/book", "/book/*");
	}
	
	@Override
	protected void addResourceHandlers(ResourceHandlerRegistry registry) {
		// 添加对静态资源的访问
	}
}
@ComponentScan({"com.tyt.controller", "com.tyt.config"})
@EnableWebMvc
public class SpringMvcConfig{
}

方法② :直接在SpringMVC核心配置类实现WebMvcConfigurer 接口并注册拦截器(此方法较方法①更加简化,当侵入式较强)

@ComponentScan({"com.tyt.controller"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {

	@Autowired
	private ProjectInterceptor projectInterceptor;
	
	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry){
		// 添加对静态资源的访问
	}
	

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 添加拦截器并设定拦截的访问路径,路劲可以通过可变参数设置多个
		registry.addInterceptor(projectInterceptor).addPathPatterns("/book", "/book/*");
	}
}

三、拦截器链

  • 当配置多个拦截器时,形成拦截器链
  • 拦截器链的运行顺序参照拦截器添加顺序为准
  • 当拦截器中出现对原始处理的拦截,后面的拦截器均终止运行
  • 当拦截器运行中断,仅运行配置在前面的拦截器的afterCompletion操作

假设现在有拦截器1、2、3,分别用pre1、post1、after1;pre2、post2、after2;pre3、post3、after3来描述各拦截器方法。

在这里插入图片描述

① 三个拦截器的preHandle均返回true

在这里插入图片描述


② 拦截器3的preHandle返回false
在这里插入图片描述


③ 拦截器2的preHandle返回false

在这里插入图片描述


④ 拦截器1的preHandle返回false

在这里插入图片描述

下期文章:

Spring 学习总结笔记【十二、Spring事务管理】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值