又是美好的一天呀~
个人博客地址: huanghong.top
本文预估阅读时长为10分钟左右~
执行逻辑
filterChain有一个filters的属性数组(过滤器链),filters中存放的是ApplicationFilterConfig 是FilterConfig的实现类,ApplicationFilterConfig中filterDef属性是过滤器定义,filterDef中的FilterClass和FilterName保存了过滤器类和过滤器名,可以根据过滤器类或名字找到要剔除的过滤器,然后将对应的ApplicationFilterConfig 从数组里剔除就可以了。
通过反射修改属性
- ApplicationFilterConfig中filters数组需要置空指定过滤器后进行重新排序(过滤器链执行到为null过滤器会报错)
- filterChain中过滤器个数属性n
代码示例
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