转自:

  https://blog.csdn.net/cp026la/article/details/86501019

简介:

  本章介绍拦截器、过滤器、切片对请求拦截的使用与区别,以及监听器在 springboot1.5 中的简单使用

过滤器、拦截器、切片拦截请求的对比:

相同点: 都可以对请求进行拦截。
不同点:
1、过滤器对请求的拦截只能获取到原始的Request 和 Response 的信息。
2、拦截器对请求的拦截可以获取原始的Request、Response和所有的controller及方法名,但无法获取方法的参数信息。
3、Aspect切片只能获取方法的参数,原始的Request、Response不能获取。

所以,实际项目需根据需求选择使用何种方式拦截请求。

一、过滤器:

1、实现Filter接口

/**
* @Auther: xf
* @Date: 2018/11/19 19:30
* @Description: 自定义过滤器
*
* Filter 只能获取request 和 response 并不知道请求是哪个 controller 处理的
*/
@Slf4j
public class CustomFilter implements Filter { @Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("过滤器初始化>>>>>>>");
} /**
* 请求被拦截的时候进行调用
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info(">>>>>>>>>>>>过滤器拦截请求处理逻辑>>>>>>>>>>>>>"); // 业务逻辑
long startTime = System.currentTimeMillis(); // 过滤器链,给下一个过滤器
filterChain.doFilter(servletRequest, servletResponse);
log.info("请求时间:" + (System.currentTimeMillis() - startTime));
} @Override
public void destroy() {
log.info("过滤器销毁>>>>>>>");
}
}  

2、过滤器配置类:

传统的web项目中,过滤器的配置是在web.xml中添加。SpringBoot需要使用FilterRegistrationBean来完成配置。

/**
* @Auther: xf
* @Date: 2018/11/19 19:58
* @Description: 传统的项目配置 Filter 在 web.xml 中添加
* 在Spring boot中,我们需要 FilterRegistrationBean 来完成配置
*/
@Configuration
public class CustomFilterConfig {
@Bean
public FilterRegistrationBean customFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CustomFilter());
registration.addUrlPatterns("/*");
registration.setName("customFilter");
registration.setOrder(1);
return registration;
}
}  

3、启动项目,随便请求一个接口测试效果:

控制台有拦截器的日志。

4、配置过滤器的方式二:

直接通过@WebFilter注解配置(注释掉上面的CustomFilterConfig配置类)

@Slf4j
// 多个过滤器,使用此注解指定执行顺序,越小越先执行
@Order(1)
// 在 CustomFilterConfig 中配置 注释掉 @WebFilter
@WebFilter(urlPatterns = "/*", filterName = "customFilter")
public class CustomFilter implements Filter {
...
}  

注意:
@WebFilter 是Servlet3.0 的规范,并不是SpringBoot提供的,需加上@ServletComponentScan注解扫描指定的包。我们这里加到启动类上。

// filter和servlet、listener之类的需要单独进行注册才能使用,spring boot里面提供了该注解起到注册作用
@ServletComponentScan
// mapper 接口类扫描包配置
@MapperScan("com.coolron.*.dao")
@SpringBootApplication(scanBasePackages = "com.coolron")
public class SpringbootApplication {
...
}  

二、拦截器:

1、自定义拦截器1:

@Slf4j
public class MyInterceptor1 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info(">>>MyInterceptor1>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");
return true;// 只有返回true才会继续向下执行,返回false取消当前请求
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.info(">>>MyInterceptor1>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
log.info(">>>MyInterceptor1>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
}
}  

2、自定义拦截器2:

/**
* 自定义拦截器2
*/
@Slf4j
public class MyInterceptor2 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
log.info(">>>MyInterceptor2>>>>>>>在请求处理之前进行调用(Controller方法调用之前)");
return true;// 只有返回true才会继续向下执行,返回false取消当前请求
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
log.info(">>>MyInterceptor2>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
log.info(">>>MyInterceptor2>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
}
}

3、拦截器配置类:

/**
* @Auther: xf
* @Date: 2018/11/19 21:09
* @Description:
*/
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
/*
* 拦截器配置
* 在spring-mvc.xml配置文件内添加<mvc:interceptor>标签配置拦截器。
*/
@Override
public void addInterceptors(InterceptorRegistry registry) { // 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**").excludePathPatterns("/login");
registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");
// 父类的配置
super.addInterceptors(registry);
}
}  

三、Aspect切片拦截:

1、自定义切片:

/**
* @Description:
* 可以拿到请求的具体controller 对应的方法的具体参数值 但是拿不到 原始的request 和 response
*
* 切入点(注解):
* 1、 在哪些方法上起作用
* 2、 什么时候起作用
*
* 增强(方法)
* 1、起作用是执行的业务逻辑
*/
// 声明切片类
@Slf4j
@Aspect
@Component
public class CustomAspect { // 在什么时候起作用
// @Before() 相当于拦截器的 PreHandle() 方法
// @After() 拦截的方法响应之后执行
// @AfterThrowing 方法抛出某些异常的时候调用
// @Around 环绕 覆盖前面三种
// 环绕的方式调用下面的方法
@Around("execution(* com.coolron.*.controller..*.*(..))")
// ProceedingJoinPoint 类 包含了当前拦截的方法的一些信息
public Object method(ProceedingJoinPoint pjp) throws Throwable {
log.info("=====Aspect处理=======");
Object[] args = pjp.getArgs();
for (Object arg : args) {
log.info("参数为:" + arg);
}
long start = System.currentTimeMillis();
// 相当于Filter 的 chain.doFilter() 调用被拦截的那个方法 返回值 object 与 controller中方法的返回值相同
Object object = pjp.proceed();
log.info("Aspect 耗时:" + (System.currentTimeMillis() - start));
return object;
}
}  

execution表达式参看SpringBoot>07 - 事物处理。

2、启动访问任意接口:

观察控制台发现Filter、Interceptor、切片执行顺序:

拦截顺序 : Filter >>> Interceptor >>> Aspect >>> controller
若果有异常返回结果: controller >>> Aspect >>> ControllerAdvice(全局异常处理类上) >>> Interceptor >>> Filter

四、监听器:

1、自定义监听器,实现ServletRequestListener接口

/**
* @Auther: xf
* @Date: 2018/11/19 21:42
* @Description: 监听器
*/
@Slf4j
@WebListener
public class RequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
log.info("监听器销毁>>>>>");
} @Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
log.info("监听器初始化>>>>>");
}
} 

2、测试:随便请求一个接口会看到监听器初始化和销毁的日志。

注意:案例中实现的是request的监听器。用于监听request对象的创建、销毁。
常见的监听器:
1、HttpSessionListener:监听session对象的创建、销毁
2、ServletRequestListener:监听request对象的创建、销毁
3、ServletContextListener:监听servletContext对象的创建、销毁

【springboot】过滤器、监听器、拦截器,Aspect切片的更多相关文章

  1. Springboot 过滤器和拦截器详解及使用场景

    一.过滤器和拦截器的区别 1.过滤器和拦截器触发时机不一样,过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的.请求结束返回也是,是在servlet处理完后,返回给前端之前. 2.拦截 ...

  2. JavaWeb过滤器.监听器.拦截器-原理&区别-个人总结

    对比项 拦截器 过滤器 机制 反射机制 函数回调 是否依赖servlet容器 是 否 请求处理 只能对action请求起作用 几乎所有的请求起作用 对action处理 可以访问action上下文.值栈 ...

  3. JavaWeb过滤器.监听器.拦截器-原理&区别(转)

    1.拦截器是基于java的反射机制的,而过滤器是基于函数回调 2.过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 3.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的 ...

  4. AOP,过滤器,监听器,拦截器【转载】

    面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承.多态和封装.而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配 ...

  5. JavaWeb过滤器.监听器.拦截器-?原理&区别

    过滤器可以简单理解为“取你所想取”,忽视掉那些你不想要的东西:拦截器可以简单理解为“拒你所想拒”,关心你想要拒绝掉哪些东西,比如一个BBS论坛上拦截掉敏感词汇. 1.拦截器是基于java的反射机制,过 ...

  6. Springboot 三种拦截Rest API的方法-过滤器、拦截器、切片

    过滤器方式实现拦截(Filter) 通过继承Servlet的Filter类来实现拦截: @Component public class TimeFilter implements Filter { @ ...

  7. springboot中过滤器、拦截器、切片使用

    直接贴代码:采用maven工程 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project ...

  8. 过滤器 & 监听器 & 拦截器

    过滤器: https://blog.csdn.net/MissEel/article/details/79351231 https://blog.csdn.net/qq_32363305/articl ...

  9. SpringBoot 过滤器和拦截器

    过滤器 实现过滤器需要实现 javax.servlet.Filter 接口.重写三个方法.其中 init() 方法在服务启动时执行,destroy() 在服务停止之前执行. 可用两种方式注册过滤器: ...

  10. springboot配置监听器、过滤器和拦截器

    监听器:listener是servlet规范中定义的一种特殊类.用于监听servletContext.HttpSession和servletRequest等域对象的创建和销毁事件.监听域对象的属性发生 ...

随机推荐

  1. python 16篇 多线程和多进程

    1.概念 线程.进程 进程 一个程序,它是一组资源的集合 一个进程里面默认是有一个线程的,主线程 多进程是可以利用多核cpu的线程 最小的执行单位 线程和线程之间是互相独立的 主线程等待子线程执行结束 ...

  2. C++11标准特性的一些理解

    (1)auto 和 decltype 关键字 在C++11之前,auto关键字用来指定存储期(C++98中指的是自动生命周期).在新标准中,它的功能变为类型推断.C++11引入auto关键词与之前C语 ...

  3. WIN10 网卡驱动异常代码56的问题及解决方法

    故障描述: 原来使用正常的一个微机室,突然一天控制端主机网络连接异常,平时的网络控制软件无法使用.检查网络配置正常,网络诊断.修复.将网卡禁用也没有效果:后来删除网卡想重装,则恶运开始,无法安装驱动: ...

  4. C语言:缓冲区

    缓冲区(Buffer)又称为缓存(Cache),是内存空间的一部分.也就是说,计算机在内存中预留了一定的存储空间,用来暂时保存输入或输出的数据,这部分预留的空间就叫做缓冲区(缓存).有时候,从键盘输入 ...

  5. web系统国际化思路

    需求:php开发多个中文系统支持国际化 思路: 提炼各个系统中的中文字符,替换为资源key. 多媒体文件中的中文定位(图片中的中文,中文录音,中文视频,中文模板等). 统一翻译文字.准备资源文件. 各 ...

  6. Python + Requests 知识点回顾

    http://www.downza.cn/soft/11145.html PS下载地址 http://www.bejson.com/jsonviewernew/ JSON的在线视图 import re ...

  7. 使用mvn命令将pom和jar上传至nexus私服

    要将自定义的jar或者pom上传至nexus私服,需要配置maven的settings文件! 上传至nexus私服配置 1. settings配置 <!-- maven设置私服对应的信息:id. ...

  8. C++五十一篇 -- VS2017开发人员新闻无法联网

    参考链接:https://blog.csdn.net/zz1589275782/article/details/88364983 这几天玩了下以前的电脑,本来想更新一下Visual Studio In ...

  9. OVERLAPPED 结构

    typedef struct _OVERLAPPED { ULONG_PTR Internal; ULONG_PTR InternalHigh; union { struct { DWORD Offs ...

  10. 福昕foxit phantom pdf高级编辑器企业版10.1 pro安装破解教程

    本文提供福昕foxit phantom pdf高级编辑器企业版10.1的安装教程.pj教程,可以使用全部功能,注意的是此方法对个人版无效. 没有必要再尝试别的文章,仅看这一篇即可!别的文章亲测是通过修 ...