【springboot】过滤器、监听器、拦截器,Aspect切片

转自:

  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对象的创建、销毁

原文地址:https://www.cnblogs.com/wjqhuaxia/p/12148842.html

时间: 2024-08-02 00:26:30

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

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

1.拦截器是基于java的反射机制,过滤器是基于函数回调 2.拦截器不依赖与servlet容器,过滤器依赖与servlet容器3.拦截器只能对action请求起作用,过滤器则可以对几乎所有的请求起作用 4.拦截器可以访问action上下文.值栈里的对象,而过滤器不能 5.在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次 拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,

springboot 过滤器、拦截器、消息转换器、切片执行顺序 及区别

request 请求 -->1:过滤器 doFilter2:拦截器 preHandle3:消息转换器 readInternal4:AOP before5:Controller6:Response7:AOP after8:消息转换器 writeInternal9:拦截器 postHandle 过滤器:可以拿到原始的Http请求和响应的信息,只能获得其请求和响应携带的参数,但是却拿不到真正处理请求的控制器和方法的信息拦截器: 可以拿到原始Http请求和响应的信息 也可拿到请求的方法的信息切片 :可拿

关于过滤器,拦截器,监听器

链接:https://www.zhihu.com/question/35225845 过滤器(Filter): 过滤器换一种表达就是预处理(pre processing)或者后处理(post processing),你说到的依赖于servlet容器,我觉得这是狭隘层次上的定义,你用米进行煮饭前要做什么,要用水先对米进行清洗,浸泡一下,这就是预处理:你榨完果汁后是直接喝吗,不,还要用筛子将果渣过滤掉,这就是后处理,对数据进行预处理或者后处理就是过滤器要做的工作,常见的应用有将请求中的数据进行转码,

springBoot之配置文件的读取以及过滤器和拦截器的使用

前言 在之前的学习springBoot中,成功的实现了Restful风格的基本服务.但是想将之前的工程作为一个项目来说,那些是仅仅不够的.可能还需要获取自定义的配置以及添加过滤器和拦截器.至于为什么将这些写在一起,只是因为这些比较简单而且也会经常用到,所以干脆就一起写出来了. 读取配置文件 在使用maven项目中,配置文件会放在resources根目录下. 我们的springBoot是用Maven搭建的,所以springBoot的默认配置文件和自定义的配置文件都放在此目录. springBoot

springboot环境下配置过滤器和拦截器

以前我们在配置过滤器和拦截器的时候,都是一个类继承一个接口,然后在xml中配置一下就ok 但是,但是,这是springboot的环境,没有xml的配置.所以我们还要继续学习啊啊啊啊啊~~~~~ 先简单大致说明一下,过滤器我们可以直接在类上加上@Component注解实现,但是有些参数啥的还是不好配置,还是需要一个配置文件来搞,所以,spring给我们提供了一个注解,就相当于xml,然后每个方法返回一个对象用@Bean来标注,相当于<bean></bean>注解   看代码吧 Tim

过滤器、拦截器、监听器

原文:https://www.zhihu.com/question/35225845/answer/61876681 从设计模式的角度分析它们的不同. 过滤器(Filter):当你有一堆东西的时候,你只希望选择符合你要求的某一些东西.定义这些要求的工具,就是过滤器. 拦截器(Interceptor):在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情. 监听器(Listener):当一个事件发生的时候,你希望获得这个事件发生的详细信息,而并不想干预这个事件本身的进程

Java中的过滤器,拦截器,监听器---------简单易懂的介绍

过滤器: 过滤器其主要特点在于:取你需要的东西,忽视那些不需要的东西!在程序中,你希望选择中篇文章中的所有数字,你就可以针对性的挑选数字! 拦截器: 拦截器其主要特点在于:针对你不要的东西进行拦截,比如说,在一个BBS里面你希望人家不要留“小乌鸦”的这个词,那你就可能采用拦截器! 监听器: 是一个事件处理过程,这个过程的取舍,可以让你的代码成为过滤器,还是成为拦截器~~~比如,你想监听一段用户的数据中有没有1有的话就打印111!这就需要程序都监听用户输入的东西了!if(***..equls('1

【java web】过滤器、拦截器、监听器的区别

一.对比: 1.1 过滤器和拦截器的区别: ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用. ④拦截器可以访问action上下文.值栈里的对象,而过滤器不能访问. ⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次. ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注

springboot三种拦截器的使用与比较

springboot中有三种拦截器可供选择:filter.interceptort和aop.本文主要讨论三种拦截器的使用场景与使用方式. 下文中的举例功能是计算每个请求的从开始到结束的时间,例子来源是慕课网. 一.filter 特点:可以获取原始的ServletRequest,但无法获取具体方法 实现: 1.继承javax.servlet.Filter类, [email protected]注解将其注入到框架中 3.实现其中的dofilter方法,所有的请求都会经过该方法,可以在此计算出每个请求

java-过滤器-监听器-拦截器

1.过滤器 Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码.做一些业务逻辑判断等.其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request.Response)统一设置编码,简化操作:同时还可进行逻辑判断,如用户是否已经登陆.有没有权限访问该页面等等工作.它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用