Springboot中跳过指定过滤器

又是美好的一天呀~
个人博客地址: huanghong.top

本文预估阅读时长为10分钟左右~

执行逻辑

filterChain有一个filters的属性数组(过滤器链),filters中存放的是ApplicationFilterConfig 是FilterConfig的实现类,ApplicationFilterConfig中filterDef属性是过滤器定义,filterDef中的FilterClass和FilterName保存了过滤器类和过滤器名,可以根据过滤器类或名字找到要剔除的过滤器,然后将对应的ApplicationFilterConfig 从数组里剔除就可以了。

通过反射修改属性

  1. ApplicationFilterConfig中filters数组需要置空指定过滤器后进行重新排序(过滤器链执行到为null过滤器会报错)
  2. filterChain中过滤器个数属性n

image-20230313104919977

代码示例

package com.huang.filter;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Time 2023-03-13 10:19
 * Created by Huang
 * className: DemoOncePerRequestFilter
 * Description:
 */
@Slf4j
@Component
public class DemoOncePerRequestFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //参数获取或路径判断对指定请求进行处理
        String cas = request.getParameter("cas");
        if (!"1".equals(cas)) {
            log.info("DemoOncePerRequestFilter start solving");
            try {
                //获取过滤器链中的filters属性
                Field filtersField = filterChain.getClass().getDeclaredField("filters");
                //反射设置属性可达
                filtersField.setAccessible(true);
                //获取filters属性值
                FilterConfig[] filters = (FilterConfig[]) filtersField.get(filterChain);
                //跳过过滤器个数记录
                int k = 0;
                //遍历所有过滤器
                for (int i = 0; i < filters.length; i++) {
                    if (filters[i] != null) {
                        //获取过滤器filterDef属性
                        Field filterDefField = filters[i].getClass().getDeclaredField("filterDef");
                        filterDefField.setAccessible(true);
                        //获取filter的class
                        Field filterClassField = filterDefField.get(filters[i]).getClass().getDeclaredField("filterClass");
                        filterClassField.setAccessible(true);
                        String filterClass = (String) filterClassField.get(filterDefField.get(filters[i]));
                        String FILTER_REFERENCE = "edu.yale.its.tp.cas.client.filter.CASFilter";
                        //跳过指定过滤器处理
                        if (FILTER_REFERENCE.equals(filterClass)) {
                            filters[i] = null;
                            k++;
                            break;
                        }
                        //属性可达关闭
                        filterClassField.setAccessible(false);
                        filterDefField.setAccessible(false);
                    }
                }
				//过滤器数组重新赋值,调整移除指定过滤器后过滤器数组
                int index = 0;
                for (int i = 0; i < filters.length; i++) {
                    if (index == 0 && filters[i] == null) {
                        index = i;
                    } else if (index != 0 && filters[i] != null) {
                        filters[index] = filters[i];
                        filters[i] = null;
                        i = index;
                        index = 0;
                    }
                }
				//n值重新赋值
                filtersField.setAccessible(false);
                Field n = filterChain.getClass().getDeclaredField("n");
                n.setAccessible(true);
                n.set(filterChain, n.getInt(filterChain) - k);
                n.setAccessible(false);
                log.info("DemoOncePerRequestFilter end solving");
            } catch (Exception e) {
                log.error("DemoOncePerRequestFilter doFilter exception ", e);
            }
        }
        filterChain.doFilter(request,response);
    }
}

感谢阅读完本篇文章!!!
个人博客地址: huanghong.top

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
好的,关于 Spring Boot 项目过滤器的编写,可以按照以下步骤进行: 1. 创建一个过滤器类 在 Spring Boot 项目,可以通过实现 javax.servlet.Filter 接口来创建一个过滤器类。在该类,需要重写 doFilter() 方法来实现过滤逻辑。 例如,创建一个名为 MyFilter 的过滤器类: ``` public class MyFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 过滤逻辑 chain.doFilter(request, response); // 继续执行下一个过滤器或目标资源 } } ``` 2. 配置过滤器 在 Spring Boot 项目,可以通过在配置类声明一个名为 registrationBean 的 Bean,并在其进行过滤器的配置。 例如,在一个名为 MyConfiguration 的配置类,声明一个名为 myFilter 的过滤器,并将其配置到路径为 /api/* 的请求: ``` @Configuration public class MyConfiguration { @Bean public MyFilter myFilter() { return new MyFilter(); } @Bean public FilterRegistrationBean<MyFilter> registrationBean(MyFilter myFilter) { FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(myFilter); registrationBean.addUrlPatterns("/api/*"); return registrationBean; } } ``` 在以上代码,通过 @Bean 注解声明了一个名为 myFilter 的 Bean,并通过另一个名为 registrationBean 的 Bean 进行过滤器的配置。在 registrationBean ,将 myFilter 设置为要配置的过滤器,并设置了过滤的请求路径为 /api/*。 这样,当请求路径为 /api/* 时,就会触发 MyFilter 过滤器的 doFilter() 方法,从而实现过滤功能。 以上就是 Spring Boot 项目过滤器的编写和配置方法,希望对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢正常冰的冰美式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值