【问题标题】:How to do filter mapping in AbstractAnnotationConfigDispatcherServletInitializer Spring如何在 AbstractAnnotationConfigDispatcherServletInitializer Spring 中进行过滤器映射
【发布时间】:2014-10-02 06:38:55
【问题描述】:

问题来了:我可以成功注册过滤器,但是不知道如何使用这个特定的配置来设置映射URL。

这是我的班级:

public class WebInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[]{AppConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[]{WebConfig.class};
    }

    @Override
    protected Filter[] getServletFilters() {

        return new Filter[]{
            new DelegatingFilterProxy("springSecurityFilterChain"),
            new DelegatingFilterProxy("customFilter")
        };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

P.D. 我使用WebApplicationInitializer 完成了它,但我想使用AbstractAnnotationConfigDispatcherServletInitializer

【问题讨论】:

  • A DelegatingFolterProxy 的目的是委托给实现 Filter 接口的 Spring bean,因此过滤器映射必须在您作为参数传递给 DelegatingFilterProxy 的 bean 名称的定义中。
  • 你能告诉我如何做到这一点的样本吗?对我来说不是那么清楚。

标签: java spring servlet-filters spring-java-config


【解决方案1】:

我能够做到这一点的唯一方法是使用 FilterRegistration.Dynamic 接口。在您的 WebInitializer 类中,在 onStartup 方法中手动添加您的自定义过滤器(来自超类的覆盖)。据我所知,目前没有比这更优雅的方法了。

@Override
public void onStartup(ServletContext servletContext)
        throws ServletException {
      FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("my-filter", new MyFilter());
      encodingFilter.setInitParameter("blah", "blah");
      encodingFilter.addMappingForUrlPatterns(null, false, "/toBeFiltered/*");

    super.onStartup(servletContext);
}

如果您希望此过滤器正常工作,那么最好注释掉您已覆盖的 getServletFilters 方法,以便从 servletContext 正确返回此过滤器。

【讨论】:

  • 是的,我也是,我希望有一种方法可以在不覆盖 onStartup 方法的情况下做到这一点。
  • 我同意,但它不是那么糟糕的解决方案.. 至少它可以在不诉诸完全骇客的情况下完成!如果您对此不满意,可以在 Spring 的 jira 上解决它 - jira.spring.io/browse/SPR
  • @dectarin 非常感谢。我试图让我的 characterEncodingFilter 正常工作好几天。简单地使用“getServletFilters”方法的建议解决方案在任何情况下都不起作用。
  • super.onStartup(servletContext);不能放在那条线上。
【解决方案2】:

对于springSecurityFilterChain,只需将该类添加到与其他配置类相同的包中

@Order(2)
public class MyAppSecureWebAppInitializer extends
    AbstractSecurityWebApplicationInitializer {

  @Override
  protected boolean enableHttpSessionEventPublisher() {
    return true;
  }
}

AbstractSecurityWebApplicationInitializer(来自 javadocs)

注册 DelegatingFilterProxy 以使用 springSecurityFilterChain 在任何其他注册的过滤器之前。什么时候 与 AbstractSecurityWebApplicationInitializer(Class) 一起使用,它将 还注册一个 ContextLoaderListener。当与 AbstractSecurityWebApplicationInitializer(),这个类通常是 与 AbstractContextLoaderInitializer 的子类一起使用。

默认情况下,DelegatingFilterProxy 是在不支持的情况下注册的, 但可以通过覆盖 isAsyncSecuritySupported() 和 getSecurityDispatcherTypes()。

之前和之后的附加配置 springSecurityFilterChain 可以通过覆盖添加 afterSpringSecurityFilterChain(ServletContext).

还有来自 spring 安全示例 in Github

@Override
protected Filter[] getServletFilters() {
    CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
    encodingFilter.setEncoding("UTF-8");
    encodingFilter.setForceEncoding(true);

    DelegatingFilterProxy reconnectDelegate = new DelegatingFilterProxy("apiExceptionHandler");

    return new Filter[] { reconnectDelegate, encodingFilter, new HiddenHttpMethodFilter() };
}

【讨论】:

  • 谢谢你的澄清,但我的问题是我在哪里可以告诉过滤器什么时候映射?,要过滤的 Url,因为默认情况下它是从“/”映射的正如 getServletMappings() 方法所说。
猜你喜欢
  • 1970-01-01
  • 2014-05-20
  • 2018-09-13
  • 2022-07-25
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-15
相关资源
最近更新 更多