SpringBoot, как установить порядок фильтра без аннотации

Я пытаюсь вставить (в первую позицию) простой пользовательский фильтр Cors в цепочку пружинных фильтров.

Если я сделаю это так

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {

он отлично работает, я могу проверить это, поставив точку останова в Spring ServletHandler.java, где есть строка

chain=getFilterChain(baseRequest, target, servlet_holder);

Мне просто интересно, хочу ли я не использовать @Componenent and @Order и вместо этого определить bean-компонент фильтра в контексте приложения. Как установить порядок фильтров?


person Johny19    schedule 07.07.2016    source источник
comment
Использование @Component определяет его как bean-компонент. Но если необходимо, создайте метод ``@Bean` для файловой системы, а также добавьте FilterRegistrationBean и установите его свойство order.   -  person M. Deinum    schedule 07.07.2016
comment
ага вот спасибо!   -  person Johny19    schedule 07.07.2016


Ответы (3)


См. пример: в вашем классе ServletInitializer:

@Bean
 public FilterRegistrationBean requestLogFilter() {
        final FilterRegistrationBean reg = new FilterRegistrationBean(createRequestLogFilter());
        reg.addUrlPatterns("/*");
        reg.setOrder(1); //defines filter execution order
        return reg;
 }

 @Bean
 public RequestLogFilter createRequestLogFilter(){
        return new RequestLogFilter();
 }

имя моего фильтра "requestLogFilter"

Предупреждение: не используйте аннотацию @Component в классе Filter.

person Carlos Felipe Ribeiro Maradeia    schedule 07.07.2016
comment
Решил мою проблему. Спасибо, что поделился! - person Douglas Ribeiro; 07.07.2016

В случае corsFilter обычно требуется установить порядок загрузки этого фильтра до того, как springSecurityFilterChain и другие фильтры, такие как errorPageFilter из весенней загрузки, будут загружены в самое начало цепочки. В противном случае поддержка CORS будет нарушена, и необходимые заголовки не будут введены. Это может быть достигнуто в следующем вопросе:

@Configuration
public class MyConfiguration {

    @Bean
    public FilterRegistrationBean corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://domain1.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(Integer.MIN_VALUE);
        return bean;
    }
}

bean.setOrder(Integer.MIN_VALUE) гарантирует, что это самый первый загруженный фильтр. Даже если есть другие фильтры, такие как фильтр errorPage с порядком, установленным на Integer.MIN_VALUE (-2147483648).

person megalucio    schedule 19.07.2016
comment
Ваше решение отлично работает для меня. Однако я не понимаю, почему. Я думаю, что это ошибка или недостаток CorsFilter. - person chenatu; 13.03.2017
comment
Я бы не подумал, что это ошибка, я уверен, что он будет работать нормально без установки порядка в случае, когда будет использоваться только один фильтр. Однако в случае, когда вы используете другие фильтры, такие как защита пружины, вам необходимо установить правильный порядок цепочки по порядку. - person megalucio; 13.03.2017
comment
@megalucio Я получаю исключение, пока делаю то же самое, что и вы. ИСКЛЮЧЕНИЕ Вызвано: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Ожидается, что компонент с именем 'corsFilter' будет иметь тип 'org.springframework.web.filter.CorsFilter', но на самом деле имел тип 'org.springframework.boot.web. servlet.FilterRegistrationBean' - person Mubasher; 10.01.2019
comment
просто изменение corsFilter() на corsFilterBean() сработало для меня. - person Mubasher; 10.01.2019

Другой альтернативой является реализация вашего фильтра org.springframework.core.Ordered, и это единственный вариант, если вы используете spring webflux (у него нет FilterRegistrationBean):

public class CorsFilter implements Filter, Ordered {
    //...

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE
    }
}

или вы даже можете сделать его переменной в своем фильтре.

person Vedavyas Bhat    schedule 15.01.2020