Spring Boot 拦截器

Spring Boot 拦截器上一篇对过滤器的定义做了说明,也比较简单。过滤器属于Servlet范畴的API,与Spring没什么关系。Web开发中,我们除了使用Filter来过滤请web求外,还可以使用Spring提供的HandlerInterceptor(拦截器)。HandlerInterceptor的功能跟过滤器类似,但是提供更精细的的控制能力:在request被响应之前、request被响应之后、视图渲染之前

大家好,又见面了,我是你们的朋友全栈君。

上一篇对过滤器的定义做了说明,也比较简单。过滤器属于Servlet范畴的API,与Spring 没什么关系。
Web开发中,我们除了使用 Filter 来过滤请web求外,还可以使用Spring提供的HandlerInterceptor(拦截器)。

HandlerInterceptor 的功能跟过滤器类似,但是提供更精细的的控制能力:在request被响应之前、request被响应之后、视图渲染之前以及request全部结束之后。我们不能通过拦截器修改request内容,但是可以通过抛出异常(或者返回false)来暂停request的执行。

实现 UserRoleAuthorizationInterceptor 的拦截器有:
ConversionServiceExposingInterceptor
CorsInterceptor
LocaleChangeInterceptor
PathExposingHandlerInterceptor
ResourceUrlProviderExposingInterceptor
ThemeChangeInterceptor
UriTemplateVariablesHandlerInterceptor
UserRoleAuthorizationInterceptor

其中 LocaleChangeInterceptor 和 ThemeChangeInterceptor 比较常用。

配置拦截器也很简单,Spring 为什么提供了基础类WebMvcConfigurerAdapter ,我们只需要重写 addInterceptors 方法添加注册拦截器。

实现自定义拦截器只需要3步:
1、创建我们自己的拦截器类并实现 HandlerInterceptor 接口。
2、创建一个Java类继承WebMvcConfigurerAdapter,并重写 addInterceptors 方法。
2、实例化我们自定义的拦截器,然后将对像手动添加到拦截器链中(在addInterceptors方法中添加)。
PS:本文重点在如何在Spring-Boot中使用拦截器,关于拦截器的原理请大家查阅资料了解。

代码示例:

MyInterceptor1.java

package org.springboot.sample.interceptor;

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

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

/**
 * 自定义拦截器1
 *
 * @author   单红宇(365384722)
 * @myblog  http://blog.csdn.net/catoop/
 * @create    2016年1月7日
 */
public class MyInterceptor1 implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println(">>>MyInterceptor1>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");
		
		return true;// 只有返回true才会继续向下执行,返回false取消当前请求
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println(">>>MyInterceptor1>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println(">>>MyInterceptor1>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
	}

}

MyInterceptor2.java

package org.springboot.sample.interceptor;

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

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

/**
 * 自定义拦截器2
 *
 * @author   单红宇(365384722)
 * @myblog  http://blog.csdn.net/catoop/
 * @create    2016年1月7日
 */
public class MyInterceptor2 implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println(">>>MyInterceptor2>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");
		
		return true;// 只有返回true才会继续向下执行,返回false取消当前请求
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println(">>>MyInterceptor2>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println(">>>MyInterceptor2>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
	}

}

MyWebAppConfigurer.java

package org.springboot.sample.config;

import org.springboot.sample.interceptor.MyInterceptor1;
import org.springboot.sample.interceptor.MyInterceptor2;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyWebAppConfigurer 
		extends WebMvcConfigurerAdapter { // 这里注意,在spring 5.0之后 WebMvcConfigurerAdapter 过时了,可以直接实现接口 implements WebMvcConfigurer(下面实现的方法是一样的)

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 多个拦截器组成一个拦截器链
		// addPathPatterns 用于添加拦截规则
		// excludePathPatterns 用户排除拦截
		registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**");
		registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");
		super.addInterceptors(registry);
	}

}

然后在浏览器输入地址: http://localhost:8080/index 后,控制台的输出为:

>>>MyInterceptor1>>>>>>>在请求处理之前进行调用(Controller方法调用之前)
>>>MyInterceptor2>>>>>>>在请求处理之前进行调用(Controller方法调用之前)
>>>MyInterceptor2>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
>>>MyInterceptor1>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
>>>MyInterceptor2>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
>>>MyInterceptor1>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)

根据输出可以了解拦截器链的执行顺序(具体原理介绍,大家找度娘一问便知)

最后强调一点:只有经过DispatcherServlet 的请求,才会走拦截器链,我们自定义的Servlet 请求是不会被拦截的,比如我们自定义的Servlet地址 http://localhost:8080/xs/myservlet 是不会被拦截器拦截的。并且不管是属于哪个Servlet 只要复合过滤器的过滤规则,过滤器都会拦截。

最后说明下,我们上面用到的 WebMvcConfigurerAdapter 并非只是注册添加拦截器使用,其顾名思义是做Web配置用的,它还可以有很多其他作用,通过下面截图便可以大概了解,具体每个方法都是干什么用的,留给大家自己研究(其实都大同小异也很简单)。
这里写图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/130001.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • request对象[通俗易懂]

    request对象[通俗易懂]request对象request对象封装了由客户端生成的HTTP请求的所有细节,主要包括HTTP头信息、系统信息、请求方式和请求参数等。通过request对象提供的相应方法可以处理客户端浏览器提交的

    2022年7月2日
  • DB4O学习笔记

    DB4O学习笔记什么是DB4O“利用表格存储对象,就像是将汽车开回家,然后拆成零件放进车库里,早晨可以再把汽车装配起来。但是人们不禁要问,这是不是泊车的最有效的方法呢。”–EstherDysondb4o是一个开源的纯面向对象数据库引擎,对于Java与.NET开发者来说都是一个简单易用的对象持久化工具,使用简单。同时,db4o已经被第三方验证为具有优秀性能的面向对象数据库,下面的基准测…

    2022年7月21日
  • B样条曲线的一些基本性质[通俗易懂]

    B样条曲线的一些基本性质[通俗易懂]1.B样条曲线的节点(knotpoint)指的是将区间划分为一段一段的分段点。节点向量(knotvector)则是由多个节点组成的向量。2.B样条曲线的次数(degree)也就是基函数的次数,而阶数(oder)则是次数加1。3.若B样条曲线由n+1个控制点(从P0到Pn),有m+1个节点(从u0到um),阶数为k+1(次数为k),则必须满足m=n+k+1。4.B样条曲线的每个控制点对应一个基函数,所有控制点与对应的基函数的乘积求和可得到B样条曲线的函数表达式。5.B样条曲线具有局部支撑性。第i+

    2022年6月18日
  • SQL语句增加字段、修改字段、修改类型、修改默认值[通俗易懂]

    SQL语句增加字段、修改字段、修改类型、修改默认值[通俗易懂]–一、修改字段默认值altertable表名dropconstraint约束名字——说明:删除表的字段的原有约束altertable表名addconstraint约束名字DEFAULT默认值for字段名称——-说明:添加一个表的字段的约束并指定默认值–二、修改字段名:altertable表名renamecolumn…

    2022年5月21日
  • map key为null_mybatis json

    map key为null_mybatis jsonmybatis返回Map结果集value为Null的情况下丢失key的解决办法本博主之前一直是网络资源的索取者,本着开源精神愿意把自己在开发过程中遇到过的问题以及解决方案分享给大家,这是我的第一篇博客,希望以后能坚持写博客,让大家少走弯路、少踩坑。废话少说,直入主题!springcloud微服务集成mybatis动态多数据源在网上有很多文章可以搜到,这里就不重复造轮子了。如题,网上…

    2022年9月28日
  • webpackdevtool配置简单对比简书_钢铁雄心4toolpack

    webpackdevtool配置简单对比简书_钢铁雄心4toolpack官方手册传送门官方对devtool配置的定义很简单:选择一种sourcemap格式来增强调试过程,不同的值会明显影响到构建build和重新构建rebuild的速度。不过,什么是sourcemap,官方用提供了许多种的sourcemap,其中的区别是什么,我们在开发中应该怎么选择,都是我们要学习的。1.什么是sourcemap现在的前端代码会通过babel编译或者各类的…

    2022年9月29日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号