Springboot 中各个filter如何调整执行顺序(通过@Order,Ordered,FilterRegistrationBean三种方式)

本文介绍了在Springboot中调整过滤器(Filter)执行顺序的三种方法:通过FilterRegistrationBean设置Order值,使用@Order注解,以及实现Ordered接口。Order值越小,Filter的执行优先级越高。通过实践测试,确认了这些方式都能有效改变过滤器的执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们在使用filter不可避免的会用到过滤器,在还未使用springboot的的项目的时候,都是讲过滤器配置在web.xml中。配置的越靠前,filter越先执行。现在很多都是用@WebFilter注解,看到下面注解源码,并没有参数指定顺序。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebFilter {
    String description() default "";

    String displayName() default "";

    WebInitParam[] initParams() default {};

    String filterName() default "";

    String smallIcon() default "";

    String largeIcon() default "";

    String[] servletNames() default {};

    String[] value() default {};

    String[] urlPatterns() default {};

    DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST};

    boolean asyncSupported() default false;
}

我们可以同Order来自指定Filter执行顺序,可以通过三种方式来指定Order的值,Order值越小执行优先级越高。
1、通过FilterRegistrationBean 来设置Order的优先级

@Configuration
public class RequestBodyConfig {

    @Bean
    public FilterRegistrationBean requestBodyFilterRegistration(){
        FilterRegistrationBean registration = new FilterRegistrationBean();
        //添加过滤器
        registration.setFilter(new RequestBodyFilter());
        //设置过滤路径,/*所有路径
        registration.addUrlPatterns("/*");
        registration.setName("requestBodyFilter");
        //设置优先级
        registration.setOrder(0);
        return registration;
    }

    public class RequestBodyFilter implements Filter {
        @Override
        public void destroy() {

        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("在requestbodyFilter执行代码");
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            //防止读流一次之后就没有了,所以将流继续写出去
            BodyReaderHttpServletRequestWrapper requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
            filterChain.doFilter(requestWrapper, response);

        }

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {

        }
    }

    /**
     * request.getInputStream();
     * request.getReader();
     * 和request.getParameter("key");
     * 保存流
     */
    public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper{
        private final byte[] body;
        public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
            String bodyString = StreamUtil.getBodyString(request);
            body = bodyString.getBytes(Charset.forName("UTF-8"));

        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);
            return new ServletInputStream() {
                @Override
                public boolean isFinished() {
                    return false;
                }

                @Override
                public boolean isReady() {
                    return false;
                }

                @Override
                public void setReadListener(ReadListener readListener) {

                }

                @Override
                public int read() throws IOException {
                    return byteArrayInputStream.read();
                }
            };
        }

        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(getInputStream()));
        }
    }
}

2、@Order方式设置Order值

@Component
@WebFilter(filterName = "signFilter", urlPatterns = "/*")
@Order(-1)
public class SignFilter implements Filter {
    private static final Logger LOGGER = LoggerFactory.getLogger(SignFilter.class);
    /**
     * 正常情况是通过配置文件获取
     */
    private static final String key = "ABCD";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
   
        System.out.println("在signFilter执行代码");
   

    }

    @Override
    public void destroy() {

    }

}

3、通过实现Orderd接口指定Ordered 值

@Component
@WebFilter(filterName = "signFilter", urlPatterns = "/*")
public class SignFilter2 implements Filter,Ordered {
    private static final Logger LOGGER = LoggerFactory.getLogger(SignFilter2.class);
    /**
     * 正常情况是通过配置文件获取
     */
    private static final String key = "ABCD";

    private int order=-2;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
       
        System.out.println("在signFilter2执行代码");
     

    }

    @Override
    public void destroy() {

    }

    @Override
    public int getOrder() {
        return this.order;
    }
    
}

查看执行结果,通过测试动态无论调整那个,那个filter里面的值,都能使过滤器里面的顺序生效

在signFilter2执行代码
在signFilter执行代码
在requestbodyFilter执行代码
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值