思路

首先编写程序时,或多或少会存在几个固定的Filter,那么第一步就是为确定的那几个Filter指定好顺序。(通常情况下的使用场景是:你要将你现在编写的项目打包成jar给别的项目使用)其次程序确定的几个Filter已经编写好了,那么需要将它们和不确定的那几个放在一起进行重新排序。将排好序的Filter进行注册。

补充:FilterRegistrationBean的使用

@Bean

FilterRegistrationBean filterRegistrationBean() {

FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean<>();

filterRegistrationBean.setFilter(new AFilter());

return filterRegistrationBean;

}

手动注册代码

先随便定义几个过滤器,后面备用

都一样的,我复制了几个:AFilter、BFilter、CFilter、DFilter、EFilter

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;

import java.util.Arrays;

import java.util.Map;

public class AFilter implements Filter {

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

System.out.println("A 的过滤器");

HttpServletRequest request = (HttpServletRequest) servletRequest;

Map parameterMap = request.getParameterMap();

for (Map.Entry entry : parameterMap.entrySet()) {

System.err.println("AAAA----->>>>>> " + entry.getKey() + "----" + Arrays.toString(entry.getValue()));

}

filterChain.doFilter(servletRequest, servletResponse);

}

}

调试用的controller

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class TestController {

@RequestMapping("/test")

public Object test() {

return "123";

}

}

已确定的过滤器注册类

import javax.servlet.Filter;

import java.util.HashMap;

import java.util.Map;

/**

* 已确定的过滤器排序

*/

public class InitFilterOrderRegistration {

private static final int INITIAL_ORDER = 200;

private static final int ORDER_STEP = 100;

private final Map filterToOrder = new HashMap<>();

InitFilterOrderRegistration() {

Step order = new Step(INITIAL_ORDER, ORDER_STEP);

put(AFilter.class, order.next());

put(BFilter.class, order.next());

put(CFilter.class, order.next());

}

public Map getOrderedFilterMap() {

return this.filterToOrder;

}

void put(Class filter, int position) {

String className = filter.getName();

if (this.filterToOrder.containsKey(className)) {

return;

}

this.filterToOrder.put(className, position);

}

Integer getOrder(Class clazz) {

while (clazz != null) {

Integer result = this.filterToOrder.get(clazz.getName());

if (result != null) {

return result;

}

clazz = clazz.getSuperclass();

}

return null;

}

private static class Step {

private int value;

private final int stepSize;

Step(int initialValue, int stepSize) {

this.value = initialValue;

this.stepSize = stepSize;

}

int next() {

int value = this.value;

this.value += this.stepSize;

return value;

}

}

}

手动注册Filter的类

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.config.BeanDefinition;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

import org.springframework.beans.factory.support.*;

import org.springframework.boot.web.servlet.FilterRegistrationBean;

import org.springframework.boot.web.servlet.ServletRegistrationBean;

import org.springframework.core.OrderComparator;

import org.springframework.core.Ordered;

import org.springframework.util.CollectionUtils;

import javax.servlet.*;

import java.io.IOException;

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import java.util.Map;

public class DefaultFilterRegister implements BeanDefinitionRegistryPostProcessor {

private final List filters = new ArrayList<>();

private final InitFilterOrderRegistration filterOrders = new InitFilterOrderRegistration();

private final List toRegister = new ArrayList<>();

public DefaultFilterRegister performRegister() {

Map orderedFilterMap = filterOrders.getOrderedFilterMap();

for (Map.Entry entry : orderedFilterMap.entrySet()) {

try {

OrderedFilter orderedFilter = new OrderedFilter((Filter) Class.forName(entry.getKey()).newInstance(),

entry.getValue());

this.filters.add(orderedFilter);

} catch (Exception e) {

e.printStackTrace();

}

}

//排序并构造

this.filters.sort(OrderComparator.INSTANCE);

for (OrderedFilter filter : this.filters) {

toRegister.add(filter.filter);

}

return this;

}

public DefaultFilterRegister addFilterAfter(Filter filter, Class afterFilter) {

return addFilterAtOffsetOf(filter, 1, afterFilter);

}

public DefaultFilterRegister addFilterBefore(Filter filter, Class beforeFilter) {

return addFilterAtOffsetOf(filter, -1, beforeFilter);

}

private DefaultFilterRegister addFilterAtOffsetOf(Filter filter, int offset,

Class registeredFilter) {

int order = this.filterOrders.getOrder(registeredFilter) + offset;

this.filters.add(new OrderedFilter(filter, order));

return this;

}

@Override

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

if (CollectionUtils.isEmpty(toRegister)) {

return;

}

for (Filter filter : toRegister) {

BeanDefinitionBuilder beanDefinitionBuilder =

BeanDefinitionBuilder.genericBeanDefinition(filter.getClass());

AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();

beanDefinition.setBeanClass(filter.getClass());

beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);

registry.registerBeanDefinition(filter.getClass().getName(), beanDefinition);

}

}

@Override

public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {

//可以通过这个BeanFactoryPostProcessor接口实现使某些过滤器失效的操作

DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf;

Arrays.stream(beanFactory.getBeanNamesForType(javax.servlet.Filter.class))

.forEach(name -> {

//例如让A失效

if (name.equals(AFilter.class.getTypeName())) {

BeanDefinition definition = BeanDefinitionBuilder

.genericBeanDefinition(FilterRegistrationBean.class)

.setScope(BeanDefinition.SCOPE_SINGLETON)

.addConstructorArgReference(name)

.addConstructorArgValue(new ServletRegistrationBean[]{})

.addPropertyValue("enabled", false)

.getBeanDefinition();

beanFactory.registerBeanDefinition(name + "FilterRegistrationBean",

definition);

}

});

}

private static final class OrderedFilter implements Ordered, Filter {

private final Filter filter;

private final int order;

private OrderedFilter(Filter filter, int order) {

this.filter = filter;

this.order = order;

}

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)

throws IOException, ServletException {

this.filter.doFilter(servletRequest, servletResponse, filterChain);

}

@Override

public int getOrder() {

return this.order;

}

@Override

public String toString() {

return "OrderedFilter{" + "filter=" + this.filter + ", order=" + this.order + '}';

}

}

}

注意代码里的 postProcessBeanFactory 方法,我在里面使 A 过滤器失效。这应该是通用的,如果有其他的过滤器想失效的,一样操作即可。例如Spring Security中的一堆过滤器

将DefaultFilterRegister注册成Bean

import com.kusch.filter.AFilter;

import com.kusch.filter.CFilter;

import com.kusch.filter.DefaultFilterRegister;

import com.kusch.filter.custom.DFilter;

import com.kusch.filter.custom.EFilter;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)

public class OrderedConfiguration {

@Bean

@ConditionalOnMissingBean

DefaultFilterRegister defaultFilterRegister() {

//正常的话应该是: A(被失效) E B D C

DefaultFilterRegister defaultFilterRegister

= new DefaultFilterRegister()

.addFilterBefore(new DFilter(), CFilter.class)

.addFilterAfter(new EFilter(), AFilter.class);

return defaultFilterRegister.performRegister();

}

}

以上便是手动注册Filter的全部代码,同时,如果该项目被打成jar包给其他项目使用时,自定义DefaultFilterRegister这个Bean就可以实现在内置的过滤器前面或者后面增加新的过滤器。

推荐阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: