SpringBoot中的过滤器,拦截器,监听器你真的清楚吗?

学习了将近快半年的springboot框架了,优点太多了。真的在很大程度上提高了我们的开发效率。但是,也依然存在一些盲区。就像上面提到的过滤器,拦截器,监听器你真的都清楚吗?下面我们一起来看看:

过滤器

通俗理解:当你有一堆东西的时候,你只希望选择符合你要求的某一些东西。定义这些要求的工具,就是过滤器。(理解:就是一堆字母中取一个B)。
应用场景:过滤字符编码、做一些业务逻辑判断、URL级别的权限控制,敏感词汇的过滤,等等。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。
特点:
过滤器 (实现 javax.servlet.Filter 接口)

① 过滤器是在web应用启动的时候初始化一次, 在web应用停止的时候销毁.

② 可以对请求的URL进行过滤, 对敏感词过滤,

③ 挡在拦截器的外层

④ Filter 是 Servlet 规范的一部分

拦截器

通俗理解:在一个流程正在进行的时候,你希望干预它的进展,甚至终止它进行,这是拦截器做的事情。(理解:就是一堆字母中,干预它,通过验证的少点,顺便干点别的东西)。
应用场景:
1、日志记录 :记录请求信息的日志
2、权限检查,如登录检查
3、性能检测:检测方法的执行时间。
特点:
拦截器 (实现 org.springframework.web.servlet.HandlerInterceptor 接口)

① 不依赖Spring容器, 可以使用 Spring 容器管理的Bean

② 拦截器通过动态代理进行

③ 拦截器应用场景, 性能分析, 权限检查, 日志记录

监听器

通俗理解:这就好比你在干活的时候有监工一样。时时刻刻关注着你。
应用场景:用来监听对象的创建与销毁的发生, 比如 session 的创建销毁, request 的创建销毁, ServletContext 创建销毁 。
特点:
监听器 (实现 javax.servlet.ServletRequestListener, javax.servlet.http.HttpSessionListener, javax.servlet.ServletContextListener 等等接口)

① 主要用来监听对象的创建与销毁的发生, 比如 session 的创建销毁, request 的创建销毁, ServletContext 创建销毁

我们通过一幅图来看一下他们之间的关系:
SpringBoot中的过滤器,拦截器,监听器你真的清楚吗?_第1张图片
这是过滤器和拦截器的执行顺序(监听器知道上面的就行了)。
SpringBoot中的过滤器,拦截器,监听器你真的清楚吗?_第2张图片
针对这个图再去理解上面的特点和一些使用场景你可能会更清楚。
最后在说一下:springboot中怎么去配置过滤器和拦截器

先创建一个springboot项目,目录结构如下:
SpringBoot中的过滤器,拦截器,监听器你真的清楚吗?_第3张图片
过滤器如下:

package com.tff.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class FirstFilter implements Filter {
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        logger.info("FirstFilter执行{}方法:Before","doFilter");
       /* HttpServletRequest req = (HttpServletRequest)request;
        String url = req.getRequestURI();
        if(url.contains("user")){
            chain.doFilter(request,response);
        }else {
            request.getRequestDispatcher("/failed").forward(request,response);
        }*/

        chain.doFilter(request,response);
        logger.info("FirstFilter执行{}方法:after","doFilter");
    }
}

就是实现Filter接口,重写doFilter方法。这个可以在这个方法里面过滤你要过滤的东西,也可以在其他配置类中处理(如果在这里处理,就是备注里面的内容),如果在其他配置类里面处理,请看下面(springboot项目建议在配置类中处理):

package com.tff.filter;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/***
 *  过滤器配置类
 */

public class FilterConfig  {

    /***
     *  注册第一个过滤器
     * @return
     */
    @Bean
    public FilterRegistrationBean firstFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean(new FirstFilter());
        //可不设置,默认过滤路径为/*
        registrationBean.addUrlPatterns("/user/*");
        //有多个过滤器的时候,用于设置先后的顺序
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

OK ,springboot中的过滤器就已经ok了,
在来一起看一下拦截器:
创建一个拦截器类,实现HandlerInterceptor接口,重写一下一些方法:

package com.tff.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class FirstIntercepter implements HandlerInterceptor {
    Logger logger = LoggerFactory.getLogger(this.getClass());

    /***
     *  controller方法调用前执行
     * @param request
     * @param response
     * @param handler
     * @return 往下执行则返回true 否则返回false
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        logger.info("{}类执行{}方法",this.getClass().getSimpleName(),"preHandle");
        return true;
    }

    /***
     *  controller方法调用之后视图渲染前执行
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        logger.info("{}类执行{}方法",this.getClass().getSimpleName(),"postHandle");
    }

    /***
     *  controller方法调用且视图渲染完成后执行
     * @param request
     * @param response
     * @param handler
     * @param ex
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        logger.info("{}类执行{}方法",this.getClass().getSimpleName(),"afterCompletion");
    }
}

拦截器的配置类(springboot推荐)

package com.tff.interceptor;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    /**
     *  重写添加拦截器方法
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new FirstIntercepter())
                .addPathPatterns("/**")
                .order(1);
    }
}

拦截器就配置完成了
接下来我们写一个Controller类,来进行验证下:

package com.tff.web;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class Controller {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @GetMapping("/hello")
    public String test(){
        logger.info("Controller类的{}方法执行了","hello");
        return "hello";
    }
}

浏览器地址栏输入:http://localhost:8080/user/hello
输出结果:
SpringBoot中的过滤器,拦截器,监听器你真的清楚吗?_第4张图片
这个顺序刚好跟我们上面第一张图的顺序一样,也验证了这个流程。
欢迎各位大佬批评指正!

你可能感兴趣的:(springboot)