【问题标题】:Spring injection in Filter implementation mapped in web.xml在 web.xml 中映射的过滤器实现中的 Spring 注入
【发布时间】:2017-10-01 20:38:11
【问题描述】:

web.xml:

<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.mypackage.MyFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/myFilterPattern/*</url-pattern>
</filter-mapping>

我的过滤器:

public class MyFilter implements Filter {

    @Autowired
    InjectedBean someInjectedBean;

但是,在拦截/myFilterPattern/*请求时,MyFilter.doFilter(...)中的someInjectedBean仍然为null,表示还没有被注入。相同的 bean (InjectedBean) 在 web.xml 中未引用的其他上下文组件中被很好地注入。

是不是因为容器过滤发生在 Spring 上下文之外?有没有办法在 web.xml 中映射过滤器实现中的 Spring 注入?

【问题讨论】:

    标签: java spring web.xml servlet-filters


    【解决方案1】:

    如果您正在使用 spring security 并扩展 OncePerRequestFilter,还有一个解决方案

    @Component
    public class CustomAuthorizationFilter extends OncePerRequestFilter{
    
        @Autowired
        ResourceConfig resourceConfig;
    
        public CustomAuthorizationFilter() {
                SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
        }
    //...your code
    

    重要的是从 doFilterInternal 块中的 resourceConfig 中提取详细信息,这样您才能获得值,否则您可能会以空指针异常告终。

    【讨论】:

      【解决方案2】:

      由于过滤器不是一个 spring bean(它是一个 web 组件),所以注入在它们内部不起作用。 Springs 不会注入到 Web 组件中。

      使用 DelegatingFilterProxy,这是一个过滤器实现,它将 springbean 名称作为 init 参数并将过滤器请求委托给该 bean。

      <filter>
        <filter-name>myFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
          <param-name>targetBeanName</param-name>
          <param-value>myFilterBean</param-value>
        </init-param>
      </filter>
      
      <filter-mapping>
        <filter-name>myFilter</filter-name>
        <url-pattern>/myFilterPattern/*</url-pattern>
      </filter-mapping>
      

      并在你的 spring 上下文中创建一个名为 myFilterBean 的 Bean。

      public class MyFilter extends GenericFilterBean {
      
          @Autowired
          InjectedBean someInjectedBean;
       
          @Override
          public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
              chain.doFilter(request, response);
          }
      }
      

      【讨论】:

      • 你的意思是“在你的 spring 上下文中创建一个名为 myFilterBean 的 Bean”吗?
      • Yes 创建一个名为 myFilterBean 的 bean,类型为 MyFilter。 MyFilter 可以扩展 GenericFilterBean。
      • 您认为该 bean 的范围应该在上下文中是什么?会话?
      • 可以是单例的。过滤器在应用启动时创建一次。
      • 我做了所有这些,容器呈现了一个空白页面。它不会进入MyFilter
      猜你喜欢
      • 2023-03-25
      • 1970-01-01
      • 2010-12-19
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 2014-05-01
      • 1970-01-01
      • 2014-06-15
      相关资源
      最近更新 更多