SpringBoot实现过滤器

过滤器执行概述:

请添加图片描述

基本环境

  • JDK 1.8
  • SpringBoot 2.5.6
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

Servlet原生方式

  1. 新建过滤器
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/*", filterName = "AFilter", initParams = {
        @WebInitParam(name = "encoding", value = "UTF-8-A")
})
public class AFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String encoding = filterConfig.getInitParameter("encoding");
        log.info("初始化 AFilter 参数 encoding = {}", encoding);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("AFilter 前...");
        //放行
        filterChain.doFilter(servletRequest, servletResponse);
        log.info("AFilter 后...");
    }

    @Override
    public void destroy() {
        log.info("销毁 AFilter");
    }
}
  1. 在启动类上、配置Servlet组件扫描@ServletComponentScan
    请添加图片描述

配置类方式

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Slf4j
@Configuration
public class WebMvcConfig {

    @Bean
    public FilterRegistrationBean<Filter> filterConfigurerA() {
        // 定义一个过滤器的注册bean
        FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
        // 初始化自定义filter
        Filter filterConfigurerA = new Filter() {

            @Override
            public void init(FilterConfig filterConfig) throws ServletException {
                String encoding = filterConfig.getInitParameter("encoding");
                log.info("初始化 filterConfigurerA 参数 encoding = {}", encoding);
            }

            @Override
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
                log.info("filterConfigurerA 前...");
                //放行
                filterChain.doFilter(servletRequest, servletResponse);
                log.info("filterConfigurerA 后...");
            }

            @Override
            public void destroy() {
                log.info("销毁 filterConfigurerA");
            }
        };
        // 注册过滤器到ioc容器中
        filterFilterRegistrationBean.setFilter(filterConfigurerA);
        // 设置过滤器规则
        filterFilterRegistrationBean.addUrlPatterns("/*");
        // 设置过滤器名字
        filterFilterRegistrationBean.setName("filterConfigurerA");
        // 设置参数
        filterFilterRegistrationBean.addInitParameter("encoding", "GBK-A");
        // 设置执行顺序 数字越小越先执行
        filterFilterRegistrationBean.setOrder(1);
        // 返回
        return filterFilterRegistrationBean;
    }

}

该方式不需要使用@ServletComponentScan注解,并且可以设置过滤器的执行顺序,但是与Servlet原生的方式混合使用之后,就不能控制它们一起的执行顺序了。

  • 不建议与Servlet原生方式混用。
  • 也可能是博主能力有限,还未探究出它们混用时的顺序控制,也欢迎与博主在评论区进行讨论。

组件配置方式

package com.ara.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

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

@Slf4j
@Component
@Order(-2)
public class BFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String encoding = filterConfig.getInitParameter("encoding");
        log.info("初始化 BFilter 参数 encoding = {}", encoding);
		//log.info("采用@Component和@Order(-3)可以与配置类一同设置顺序,但是不能设置初始化参数");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("BFilter 前...");
        //放行
        filterChain.doFilter(servletRequest, servletResponse);
        log.info("BFilter 后...");
    }

    @Override
    public void destroy() {
        log.info("销毁 BFilter");
    }
}

该方式也不需要使用@ServletComponentScan注解,并且可以与配置类方式混用,而且其执行顺序会按照它们的Order值进行执行,Order值越小的就越先执行。

缺点:

  • 该方式就不便于设置其加载的参数值。

总结

不建议使用Servlet原生的方式:

  • 因为这是SpringBoot项目,我们应该善于利用其容器的便利性(也就是使用配置类方式和组件配置方式)。
  • 使用Spring容器时,我们会更好的管理其执行顺序问题。

适配性:

  • 如果需要设置过滤器的启动参数,就建议采用配置类的方式
  • 如果不需要设置过滤器的启动参数,就可随意选择了。

注意:

  • 在本文中所描述的过滤器顺序是指在请求时,过滤器的执行顺序。
  • 加载和销毁的顺序是不一定的,这个好像也控制不了(这个博主暂时没有仔细研究过,欢迎讨论),我们一般也无需关心。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Spring Boot实现过滤器有两种方法: 1. 通过编写过滤器类并使用注解 @WebFilter 将其注册为过滤器。例如: ``` @WebFilter(urlPatterns = "/*") public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 处理过滤逻辑 chain.doFilter(request, response); } } ``` 2. 通过编写过滤器类并通过编写配置类来注册过滤器。例如: ``` @Configuration public class WebConfiguration { @Bean public FilterRegistrationBean<MyFilter> filterRegistrationBean() { FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new MyFilter()); registrationBean.addUrlPatterns("/*"); return registrationBean; } } ``` 注意:在 Spring Boot 2.3 及更高版本中,使用注解 @WebFilter 注册过滤器时,需要添加以下依赖: ``` <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> ``` 在 Spring Boot 2.2 及更低版本中,不需要添加此依赖。 ### 回答2: Spring Boot可以通过使用过滤器(Filter)实现对于应用程序的请求进行预处理或后处理的功能。在Spring Boot中,实现过滤器非常简单。 首先,我们需要创建一个实现javax.servlet.Filter接口的过滤器类。我们可以在过滤器类中实现对请求的预处理或后处理逻辑。例如,我们可以在过滤器中对请求进行日志记录、授权验证、防止跨站点请求伪造(CSRF)等操作。 接下来,我们需要在Spring Boot应用程序的配置文件(例如application.properties或application.yml)中配置过滤器。我们可以使用Spring Boot提供的特定属性来配置过滤器的顺序、URL匹配模式和其他属性。例如,我们可以使用以下配置来注册并配置过滤器spring.servlet.filter.order=1 spring.servlet.filter.dispatcher-types=REQUEST spring.servlet.filter.url-pattern=/api/* spring.servlet.filter.init-param.debug=true 最后,我们需要在Spring Boot应用程序的启动类(例如带有@SpringBootApplication注解的主类)中添加一个注解@ServletComponentScan,以扫描并注册我们创建的过滤器类。这将使Spring Boot自动识别并加载该过滤器实现过滤器后,当应用程序收到请求时,过滤器将自动拦截请求并执行预处理或后处理逻辑。过滤器的执行顺序可以通过配置文件中的spring.servlet.filter.order属性进行调整。 通过以上步骤,我们就可以在Spring Boot应用程序中实现一个过滤器过滤器可以帮助我们在请求到达控制器之前或返回给客户端之前对请求进行额外处理,从而实现对请求的自定义处理逻辑。 ### 回答3: Spring Boot提供了一种简单且易于实现的方式来实现过滤器。在Spring Boot中,我们可以通过创建一个实现javax.servlet.Filter接口的类来实现过滤器。 首先,我们需要在Spring Boot应用程序的代码中创建一个新的类并实现Filter接口。该类需要实现doFilter方法,该方法的目的是在请求进入Web应用程序之前或之后执行一些操作。该方法接受三个参数,分别是ServletRequest、ServletResponse和FilterChain。 在doFilter方法中,我们可以编写我们的逻辑代码来进行过滤操作。例如,我们可以检查请求的URL,如果满足我们的条件,则可以进行一些特定的处理,比如记录日志、验证权限等。然后,我们需要调用FilterChain对象的doFilter方法,以便将请求传递给下一个过滤器或Web应用程序。 接下来,我们还需要在Spring Boot应用程序的配置类中注册我们的过滤器。可以通过使用@Bean注解将过滤器类声明为一个bean,并将其添加到Spring Boot应用程序的过滤器链中。这将确保在请求到达控制器之前,我们的过滤器将被调用。 最后,我们可以通过在配置类中使用@Order注解来指定过滤器的执行顺序。如果有多个过滤器,根据需要可以使用不同的顺序来执行它们。 总的来说,Spring Boot通过实现javax.servlet.Filter接口和在配置类中注册过滤器的方式来实现过滤器。通过编写逻辑代码并将过滤器添加到过滤器链中,我们可以在请求进入Web应用程序之前或之后进行一些自定义操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值