Как добавить фильтр с помощью WebMvcConfigurerAdapter весной?

С помощью WebApplicationInitializer я могу легко добавить фильтр к ServletContext в методе onStartup().

Как добавить фильтр с WebMvcConfigurerAdapter? Должен ли я использовать XML?

ДОБАВИТЬ 1

Чтобы помочь другим легче понять Spring Web Configuration, я нарисовал следующую иллюстрацию.

Теперь вам просто нужно сначала понять rational конфигурацию Spring Web. А затем выбрать, какой класс конфигурации унаследовать и какой метод переопределить снизу.

Легче искать, чем вспоминать так много всего.

введите описание изображения здесь

И хорошая статья о Spring Web Initialization:

http://www.kubrynski.com/2014/01/understanding-spring-web-initialization.html

ДОБАВИТЬ 2

Основываясь на ответе Tunaki, я проверил файл AbstractDispatcherServletInitializer. Регистрация фильтра происходит в следующем коде:

введите описание изображения здесь

Даже если я переопределяю зеленый метод getServletFilters(), я все равно не могу получить доступ к результату Dyanmic registerServletFilter(). Итак, как я могу настроить фильтр по addMappingForUrlPatterns()?

Кажется, я have to переопределяю весь registerDispatcherServlet() метод.


person smwikipedia    schedule 01.11.2015    source источник
comment
Фильтры автоматически сопоставляются с файлом DispatcherServlet. Если вам нужно что-то еще, переопределите метод onStartup (не забудьте вызвать super.onStartup и самостоятельно зарегистрировать фильтры, как обычно. Это все еще работает...   -  person M. Deinum    schedule 02.11.2015
comment
Или просто добавьте еще один класс, реализующий WebApplicationInitializer... Их может быть несколько, а не один!   -  person M. Deinum    schedule 02.11.2015


Ответы (3)


WebMvcConfigurer — это интерфейс, который используется для настройки конфигурации на основе Java для Spring MVC, включенного через @EnableWebMvc. WebMvcConfigurerAdapter — это просто адаптер, предоставляющий пустые методы по умолчанию для этого интерфейса.

Он не настраивает DispatcherServlet, которым используются фильтры. Таким образом, вы не можете использовать WebMvcConfigurer для настройки фильтров сервлетов.

Чтобы упростить настройку фильтров, вы можете наследовать от AbstractDispatcherServletInitializer и переопределить getServletFilters():

public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {

    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] { new CharacterEncodingFilter() };
    }

}

Если вы хотите дополнительно настроить фильтр, вам придется переопределить onStartup вместо этого:

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    super.onStartup(servletContext);
    servletContext.addFilter("name", CharacterEncodingFilter.class)
                  .addMappingForUrlPatterns(null, false, "/*");
}
person Tunaki    schedule 01.11.2015
comment
Спасибо. Но даже если расширить AbstractDispatcherServletInitialier, как мне получить объект FilterRegisteration, чтобы я мог вызывать addMappingForUrlPatterns()? - person smwikipedia; 02.11.2015
comment
Мой Add1 только для справки. Мой Add2 имеет отношение к вопросу о добавлении фильтра. Вы можете игнорировать мое добавление 1. - person smwikipedia; 02.11.2015
comment
AbstractDispatcherServletInitializer также требует реализации createServletApplicationContext, getServletMappings и createRootApplicationContext, а фильтр, похоже, не применяется. - person phil294; 29.04.2018

Вы можете получить доступ к результату Dyanmic registerServletFilter() следующим образом в конфигурации вашего приложения (в частности, Инициализатор веб-приложений):

@Override
public void onStartup(ServletContext servletContext) throws ServletException {

    // Create the 'root' Spring application context
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

    rootContext.register(
        AppConfig.class,
        SecurityConfiguration.class,
        HibernateConfiguration.class 
    );

    // Add cuatom filters to servletContext
    FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("recaptchaResponseFilter", new RecaptchaResponseFilter());
    filterRegistration.setInitParameter("encoding", "UTF-8");
    filterRegistration.setInitParameter("forceEncoding", "true");
    filterRegistration.addMappingForUrlPatterns(null, true, "/*");

    // Create the dispatcher servlet's Spring application context
    AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
    dispatcherServlet.register(MVCConfig.class);

    // Register and map the dispatcher servlet
    ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");
person Psypher    schedule 17.06.2016

Вы можете создать Spring bean-компоненты, которые реализуют внутри себя Filter и @Inject ServletContext. Затем в методе @PostConstruct вы можете зарегистрировать их с помощью servletContext.addServlet("myFilter",this);

public class MyFilter implements Filter {
    @Inject
    private ServletContext servletContext;

    @PostConstruct
    public void init(){
        ServletRegistration.Dynamic filter = servletContext.addServlet("myFilter",this);
        filter.addMapping("/myMapping");
    }
}

Компонент не должен быть объявлен в rootContext, который инициализируется с помощью ContextLoaderListener(rootContext), потому что API сервлета 3.0 запрещает использование динамической регистрации для слушателей. Поэтому он должен быть объявлен в диспетчерском контексте, который передается DispatcherServlet (dispatcherContext)

public class MyWebAppInitializer implements WebApplicationInitializer {

   @Override
   public void onStartup(ServletContext container) {
     // Create the 'root' Spring application context
     AnnotationConfigWebApplicationContext rootContext =
       new AnnotationConfigWebApplicationContext();
     rootContext.register(AppConfig.class);

     // Manage the lifecycle of the root application context
     container.addListener(new ContextLoaderListener(rootContext));

     // Create the dispatcher servlet's Spring application context
     AnnotationConfigWebApplicationContext dispatcherContext =
       new AnnotationConfigWebApplicationContext();
     dispatcherContext.register(DispatcherConfig.class);

     // Register and map the dispatcher servlet
     ServletRegistration.Dynamic dispatcher =
       container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
     dispatcher.setLoadOnStartup(1);
     dispatcher.addMapping("/");
   }

}

весенний документ

person Mirak    schedule 24.10.2017