SpringBoot实现过滤器Filter的三种方式

 更新时间:2023年08月17日 11:08:25   作者:Hi Bug  
过滤器Filter由Servlet提供,基于函数回调实现链式对网络请求与响应的拦截与修改,本文讲给大家详细介绍SpringBoot实现过滤器Filter的三种方式,需要的朋友可以参考下

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

Filter 的生命周期

  • init(): 初始化Filter 实例,Filter 的生命周期与 Servlet 是相同的,也就是当 Web 容器(tomcat)启动时,调用 init() 方法初始化实例,Filter只会初始化一次。需要设置初始化参数的时候,可以写到init()方法中。
  • doFilter(): 业务处理,拦截要执行的请求,对请求和响应进行处理,一般需要处理的业务操作都在这个方法中实现
  • destroy() : 销毁实例,关闭容器时调用 destroy() 销毁 Filter 的实例。

方式① 使用Filter接口

1、在启动类添加注解@ServletComponentScan ,让 Spring 可以扫描到。
2、通过 @WebFilter 注解,将类声明为 Bean 过滤器类。此时可以指定要拦截的url , 但是不能指定过滤器执行顺序。

@Slf4j
@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
    @Resource
    private RedisTemplate redisTemplate;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //获取访问 ip 地址
        String ipAddr = getIpAddr(request);
        // 存入缓存10s不允许访问
        String key = new StringBuilder().append("bizKey").append(ipAddr).toString();
        if (redisTemplate.hasKey(key)) {
            // 访问次数自增1
            redisTemplate.opsForValue().increment(key, 1);
            log.warn("访问过快,存在强刷行为!key={}", key);
        } else {
            // 第一次访问
            redisTemplate.opsForValue().set(key, 1, 10,
                    TimeUnit.SECONDS);
        }
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } catch (Exception e) {
            log.warn("认证失败,e:{},url:{},parameters:{}", e,request.getRequestURL(),request.getParameterMap());
            servletResponse.setContentType("application/json");
            servletResponse.setCharacterEncoding("UTF-8");
            servletResponse.getWriter().write(JSONUtil.toJsonStr(Result.fail("业务执行报错~")));
        }
    }
    @Override
    public void destroy() {
        Filter.super.destroy();
    }
    public static String getIpAddr(HttpServletRequest request){
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("X-Forwarded-For");
            if (ipAddress != null && ipAddress.length() != 0 && !"unknown".equalsIgnoreCase(ipAddress)) {
                // 多次反向代理后会有多个ip值,第一个ip才是真实ip
                if (ipAddress.indexOf(",") != -1) {
                    ipAddress = ipAddress.split(",")[0];
                }
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
            }
        }catch (Exception e) {
        }
        return ipAddress;
    }
}

方式② 使用@Component注解

使用@Component注解后,可以使用@Order注解保证过滤器执行顺序,@Order 注解用于指定组件的执行顺序,其中值越小的组件优先执行。

@Component
@Order(1)
public class MyFilter1 implements Filter {
    // ...
}
@Component
@Order(2)
public class MyFilter2 implements Filter {
    // ...
}

注意:

1、不使用@Order注解,则按照filter类名的字母顺序来执行

2、方式②可以保证执行顺序, 但是过滤器不能指定拦截的url , 只能默认拦截全部

方式③ Java Config 配置类

使用 @Configuration + @Bean 配置类,注解声明Bean,交由 Spring 容器管理。此方式既能拦截Url,也能指定执行顺序

Java Config 的方式可以通过 @Bean 配置顺序或 FilterRegistrationBean.setOrder() 决定 Filter 执行顺序。(在启动类配置拦截器,此时自定义过滤器不加注解,为普通类即可) 可以指定过滤器要拦截的url 和 过滤器执行顺序, 但需要代码方式实现.

public class MyFilter1 implements Filter {
    // ...
}
public class MyFilter2 implements Filter {
    // ...
}

通过在springboot的configuration中配置不同的FilterRegistrationBean实例,来注册自定义过滤器

这里创建一个configuration类

@Configuration
public class DemoConfiguration {
    @Bean
    public FilterRegistrationBean RegistTest1(){
        //通过FilterRegistrationBean实例设置优先级可以生效
        //通过@WebFilter无效
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new Test1Filter());//注册自定义过滤器
        bean.setName("flilter1");//过滤器名称
        bean.addUrlPatterns("/*");//过滤所有路径
        bean.setOrder(1);//优先级,最顶级
        return bean;
    }
    @Bean
    public FilterRegistrationBean RegistTest2(){
        //通过FilterRegistrationBean实例设置优先级可以生效
        //通过@WebFilter无效
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new Test2Filter());//注册自定义过滤器
        bean.setName("flilter2");//过滤器名称
        bean.addUrlPatterns("/test/*");//过滤所有路径
        bean.setOrder(6);//优先级,越低越优先
        return bean;
    }
}

以上就是SpringBoot实现过滤器Filter的三种方式的详细内容,更多关于SpringBoot实现过滤器Filter的资料请关注脚本之家其它相关文章!

相关文章

  • 10分钟带你理解Java中的反射

    10分钟带你理解Java中的反射

    反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这篇文章带大家十分钟快速理解Java中的反射,有需要的可以参考借鉴。
    2016-08-08
  • Mybatis-plus如何开启二级缓存

    Mybatis-plus如何开启二级缓存

    这篇文章主要介绍了Mybatis-plus如何开启二级缓存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • java 接口回调实例详解

    java 接口回调实例详解

    这篇文章主要介绍了java 接口回调实例详解的相关资料,所谓回调就是使用java中的多态,需要的朋友可以参考下
    2017-07-07
  • SpringBoot 整合Thymeleaf教程及使用方法

    SpringBoot 整合Thymeleaf教程及使用方法

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎,它与 JSP,Velocity,FreeMaker 等模板引擎类似,也可以轻易地与 Spring MVC 等 Web 框架集成,这篇文章主要介绍了SpringBoot 整合Thymeleaf教程及使用,需要的朋友可以参考下
    2023-11-11
  • maven工程如何读取resource目录下配置文件

    maven工程如何读取resource目录下配置文件

    这篇文章主要介绍了maven工程如何读取,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Java格式化类Format解读

    Java格式化类Format解读

    Java.text.Format 是 Java 格式化的抽象基类,用于将对象格式化为指定模式的字符串,或者将指定模式的字符串解析为对象,主要包含 format 和 parseObject 方法,分别用于格式化和解析
    2024-12-12
  • 浅谈Java平台无关性

    浅谈Java平台无关性

    这篇文章主要介绍了浅谈Java平台无关性,对此感兴趣的同学,可以多了解一下
    2021-04-04
  • SpringCloud Gateway中GatewayFilterChain执行流程详解

    SpringCloud Gateway中GatewayFilterChain执行流程详解

    Spring Cloud Gateway旨在为微服务架构提供一种简单有效的、统一的 API 路由管理方式。Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,它不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全、监控/埋点和限流等
    2022-10-10
  • Spring Bean的属性注入方式

    Spring Bean的属性注入方式

    这篇文章主要介绍了Spring Bean的属性注入方式的相关资料,需要的朋友可以参考下
    2018-02-02
  • Java基础之详解HashSet的使用方法

    Java基础之详解HashSet的使用方法

    今天给大家带来的是关于Java基础的相关知识,文章围绕着HashSet的使用方法展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06

最新评论