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配置用的,它还可以有很多其他作用,通过下面截图便可以大概了解,具体每个方法都是干什么用的,留给大家自己研究(其实都大同小异也很简单)。
这里写图片描述

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 外键约束

    外键约束外键作用:1.保证数据的完整性、一致性,更可靠。2.设置外键约束的两个表之间会有父子关系,即字表中外键字段的取值范围取决于父表3.设置外键一定程度上降低了数据库的速度4.字表中外键字段的

  • pycharm 查看函数帮助_WINCC记录字符串变量

    pycharm 查看函数帮助_WINCC记录字符串变量【为了方便自己以后查阅,记录下使用PyCharm时的一些小技巧】正在学习Python,在调试Python程序时,遇到了一个非常大的问题:如何能够方便地查看变量的取值呢?由于使用matlab多年,深深地习惯了Matlab方便地参考变量取值的功能,所以,对于正在学习的python没办法实时查看变量取值感到很是郁闷没想到,原来PyCharm具有这个功能,只不过之前没有发现而已对于将要调试

  • xsync 集群同步脚本「建议收藏」

    xsync 集群同步脚本「建议收藏」scp和rsync均是远程拷贝,rsync远程分发xsync集群分发脚本循环复制文件到所有节点相同的目录下新建一个脚本touchxsync.shvimxsync.sh#!/bin/bash#$#:表示传递给脚本或函数的参数个数。#1获取输入参数个数,如果没有参数,直接退出pcount=$#if((pcount==0));thenechonoargs…

  • linux .gz文件 解压缩命令的简单使用

    linux .gz文件 解压缩命令的简单使用压缩压缩文件语法gzip源文件1如压缩b.txt使用命令gzipb.txt即可注意压缩为.gz文件源文件会消失如果想保留源文件使用命令gzip-c源文件>压缩文件1如压缩b.txt且保留b.txt使用命令gzip-cb.txt>b.txt.gz压缩目录语法gzip-r目录1…

  • Broadcasts详解「建议收藏」

    Android系统和Android应用程序都可以发送和接收广播,类似于publish-subscribe设计模式。广播在某个特定事件发生时被发送,例如,当各种系统事件发生时(如系统启动或设备开始充电),Android系统就会发送广播。应用程序也可以发送自定义广播,例如,通知其他应用程序他们关注的事件(如数据下载完成)。应用程序可以注册广播接收器。当广播被发送时,系统自动将广播传递到已注册接收该…

  • django配置环境变量_python django框架

    django配置环境变量_python django框架django的环境配置1. 虚拟环境安装pip install virtualenvpip install virtualenvwrapper 扩展包export WORKON_HOME=$HOME/.virtualenvssource /usr/local/bin/virtualenvwrapper.shvi /usr/local/bin/virtualenvwrapper.sh目录下的文件进行修改成python3的路径环境生效:source .bashrc2. 虚拟环境配置mkvirt

发表回复

您的电子邮箱地址不会被公开。

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