SpringBoot很实用的请求过滤器 - FilterRegistrationBean

这篇具有很好参考价值的文章主要介绍了SpringBoot很实用的请求过滤器 - FilterRegistrationBean。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、为什么需要Filter

在日常的开发中,我们的项目可能会被各种各样的客户端进行访问,那么,一些带有意图的朋友,就会利用自己所学的技术进行有目的的访问,那么我们的服务端就不再安全和可靠,我相信每位开发者都知道爬虫这种东西,那么当我们的请求不再安全,那么我们后台的数据就会变得透明。
数据透明,是一件多么可怕的事情,在这个数字潮流时代,数据就是金钱,在生活中任何一个系统都会录入我们的个人信息。
那么对请求进行过滤、请求的校验就变得尤为重要。

2、常用的Filter方式

  1. 在很久以前的Servlet项目中,可以使用@WebFilter注解来进行Filter的配置。
  2. 在目前SpringBoot作为后端主流框架而言,使用更多的是配置FilterRegistrationBean类,本文也主要以此类来配置Filter。

两种方式都是针对于Filter接口的实现类而言的。

3、Filter接口

一般我们实现Filter接口,只需要实现doFilter方法即可,但是也可以实现另外两个方法。

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    default void destroy() {
    }
}

4、FilterRegistrationBean类

可以看到此类的内部需要一个T类型的filter属性,而这个属性也是FilterRegistrationBean的核心,后面我们只需要将自定义的Filter放入到不同的FilterRegistrationBean中就可以了。

public class FilterRegistrationBean<T extends Filter> extends AbstractFilterRegistrationBean<T> {
    private T filter;

    public FilterRegistrationBean() {
        super(new ServletRegistrationBean[0]);
    }

    public FilterRegistrationBean(T filter, ServletRegistrationBean<?>... servletRegistrationBeans) {
        super(servletRegistrationBeans);
        Assert.notNull(filter, "Filter must not be null");
        this.filter = filter;
    }

    public T getFilter() {
        return this.filter;
    }

    public void setFilter(T filter) {
        Assert.notNull(filter, "Filter must not be null");
        this.filter = filter;
    }
}

5、自定义Filter代码实现

5.1、自定义Filter

自定义的Filter不用使用@Bean进行注入

5.1.1、UserFilter拦截对用户信息的请求

public class UserFilterConfig implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("用户过滤器触发成功");
        // 核心代码省略
        filterChain.doFilter(servletRequest,servletResponse);
    }

}

5.1.2、AuthFilter拦截基本的认证信息

public class AuthFilterConfig implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("认证过滤器触发成功");
        // 核心代码省略
        filterChain.doFilter(servletRequest,servletResponse);
    }
}

5.2、配置FilterRegistrationBean类

对于不同的Filter对象需要配置不同的FilterRegistrationBean类,因为存在重复代码,所以我进行了代码提取,并且向容器中注入相应的对象。
在此配置类中我使用到了Builder这种方式来进行数据的配置,这种方式在当前的SpringBoot框架中是非常常见的,这种方式也非常的好用,值得学习。

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<UserFilterConfig> userFilterConfigFilterRegistrationBean(){
        FilterRegistrationBean<UserFilterConfig> userFilter = new FilterRegistrationBean<>();
        Builder<UserFilterConfig> userBuilder = new Builder<>(userFilter);
        userBuilder.filterConfiguration(UserFilterConfig.class,1,false,"/*");
        return userFilter;
    }

    @Bean
    public FilterRegistrationBean<AuthFilterConfig> authFilterConfigFilterRegistrationBean(){
        FilterRegistrationBean<AuthFilterConfig> authFilter = new FilterRegistrationBean<>();
        Builder<AuthFilterConfig> authBuilder = new Builder<>(authFilter);
        authBuilder.filterConfiguration(AuthFilterConfig.class,6,false,"/test/*");
        return authFilter;
    }


    private class Builder<T extends Filter>{

        private FilterRegistrationBean<T> filterRegistrationBean = null;

        public Builder(FilterRegistrationBean<T> filterRegistrationBean){
            this.filterRegistrationBean = filterRegistrationBean;
        }

        public Builder filterConfiguration(Class<? extends Filter> clazz,int order,boolean async,String ...patterns){
            T filter = null;
            try {
                filter = (T)clazz.getDeclaredConstructor().newInstance();
            } catch (Exception e) {
                System.out.println("[ " + clazz.toString() + " ] 过滤器对象不存在");
            }
            this.filterRegistrationBean.setFilter(filter); // 设置过滤器
            this.filterRegistrationBean.setOrder(order); // 设置启动顺序
            String clazzPath = clazz.toString().toLowerCase(Locale.ROOT);
            // 配置过滤器的名称,首字母一定要小写,不然拦截了请求后会报错
            this.filterRegistrationBean.setName(clazzPath.substring(clazzPath.lastIndexOf(".")));
            this.filterRegistrationBean.addUrlPatterns(patterns); // 配置拦截的请求地址
            return this;
        }

    }
}

6、运行结果

6.1、Controller类如下:

@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class FilterDemoController {

    private final ApplicationContext applicationContext;

    @GetMapping(value = "/abc")
    public void show(){
        for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
            if(beanDefinitionName.contains("Filter")){
                System.out.println(beanDefinitionName);
            }
        }
        System.out.println("=====> end <=====");
    }

    @GetMapping(value = "/test/abc")
    public void test(){

    }
}

/abc:会打印当前容器中所有的Filter对象。
/test/abc:什么也不做。

6.2、控制台显示

当我访问http://localhost:8080/abc时,就会触发UserFilter这个过滤器,结果如下:
SpringBoot很实用的请求过滤器 - FilterRegistrationBean

可以看到,过滤器会先触发,然后打印出所有的Filter,容器中会存在两个不同的FilterRegistrationBean。

当我访问http://localhost:8080/test/abc时,就会触发AuthFilter这个过滤器,结果如下:
SpringBoot很实用的请求过滤器 - FilterRegistrationBean

耶??为啥结果不是想象的那样??
这是因为我的UserFilter的拦截路径为/*,而AuthFilter的拦截路径为/test/*
那为什么UserFilter会在AuthFilter之前执行呢?
因为/*的拦截范围比/test/*的范围大,可以说/test/*是经过了/*拦截过再进行了匹配拦截。于此同时,我在相应的FilterRegistrationBean中也设置了Filter的执行顺序。文章来源地址https://www.toymoban.com/news/detail-465703.html

7、总结

  1. 使用Builder这种方式对配置类中的数据进行配置,是当前许多框架都在使用的方式,能够在一定程度上隐藏内部的实现。
  2. FilterRegistrationBean类提供了自定义FIlter的执行顺序,上文的Demo中因为拦截的范围问题,所以不容易看出存在执行顺序的问题,但是想要看到顺序问题也非常的简单,重新给setOrder方法赋值就行了,优先级低的先执行

到了这里,关于SpringBoot很实用的请求过滤器 - FilterRegistrationBean的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java在过滤器中为http请求加请求头header

            现在有一个需求场景:每一个请求我都需要在请求头里面加上token这个请求头,作为一种校验机制,传统的接口可以通过设置一个全局的变量,然后通过页面携带过来(大概就是先将我们的token放在session中,写一个服务用来获取session中的token,然后主页面用 ajax 调

    2024年02月12日
    浏览(36)
  • springboot使用过滤器

    过滤器是处于客户端与服务器资源文件之间的一道过滤网,帮助我们过滤一些不符合要求的请求。通常用作 Session校验,判断用户权限。 使用过滤器很简单,只需要实现Filter类,然后重写它的3个方法即可。 init方法:程序启动调用Filter的init()方法(永远只调用一次);在容器中

    2024年02月15日
    浏览(52)
  • Springboot 过滤器

    拦截器和过滤器的区别: 过滤器(Filter) :可以拿到原始的http请求,但是拿不到你请求的控制器和请求控制器中的方法的信息。 拦截器(Interceptor):可以拿到你请求的控制器和方法,却拿不到请求方法的参数。 切片(Aspect): 可以拿到方法的参数,但是却拿不到http请求和

    2023年04月15日
    浏览(36)
  • SpringCloud GateWay通过过滤器GatewayFilter修改请求或响应内容

    Spring Cloud Gateway在有些场景中需要获取request body内容进行参数校验或参数修改,我们通过在GatewayFilter中获取请求内容来获取和修改请求体,下面我们就基于ServerWebExchange来实现: ServerWebExchange命名为服务网络交换器,存放着重要的请求-响应属性、请求实例和响应实例等等,有

    2024年02月16日
    浏览(50)
  • springboot 过滤器链 来自 chatgpt

    当需要在Spring Boot中配置多个过滤器时,可以按照以下步骤进行操作: 创建多个自定义过滤器类:首先,你需要创建多个实现 javax.servlet.Filter 接口的自定义过滤器类,每个过滤器类都需要实现 doFilter 方法来定义过滤器的逻辑处理。 配置过滤器链:在Spring Boot应用程序的配置

    2024年02月12日
    浏览(41)
  • springboot中使用filter过滤器

    filter过滤器其实是JavaEE中的规范,JavaWeb中的三大组件是filter过滤器、listener监听器,servlet服务。 过滤器的作用就是把请求拦截下来,从而对请求进行一些特殊操作,比如检验用户是否登录,判断权限,设置编码格式、敏感字符处理等。 filter过滤器中有三个方法: 分别是初始

    2024年02月08日
    浏览(50)
  • 【Spring Security】使用 OncePerRequestFilter 过滤器校验登录过期、请求日志等操作

    OncePerRequestFilter 是一个过滤器,每个请求都会执行一次;一般开发中主要是做检查是否已登录、Token是否过期和授权等操作,而每个操作都是一个过滤器,下面演示一下。 检查是否登录过期过滤器 检查是否登录过期过滤器 End

    2024年02月10日
    浏览(66)
  • SpringBoot登录校验(四)过滤器Filter

    JWT令牌生成后,客户端发的请求头中会带有JWT令牌,服务端需要校验每个请求的令牌,如果在每个controller方法中添加校验模块,则十分复杂且冗余,所以引入统一拦截模块,将请求拦截下来并做校验,这块内容可以选择两种技术: Filter过滤器 Interceptor拦截器 我们首先来学习

    2024年04月17日
    浏览(38)
  • 从Spring Cloud Gateway过滤器中获取请求体的最优方案

    在spring cloud gateway出现这个问题的时候我们第一反应应该很简单,但是真正实现的时候却有点困难。我看了很多相关的文档,感觉太多都不清晰而且解决不了问题。下面我就把我的方便理解的解决方案写下来。 1. 先重写请求体(过滤器优先级一定要在要获取body之前执行) 这

    2024年02月16日
    浏览(45)
  • SpringBoot实现过滤器Filter的三种方式

    过滤器 Filter 由 Servlet 提供,基于函数回调实现链式对网络请求与响应的拦截与修改。由于基于 Servlet ,其可以对web服务器管理的几乎所有资源进行拦截(JSP、图片文件、HTML 文件、CSS文件等)。 Filter 的生命周期 init(): 初始化Filter 实例,Filter 的生命周期与 Servlet 是相同的,

    2024年02月14日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包