spring DelegatingFilterProxy can't find filter

2019-09-10 03:08发布

问题:

My web.xml looks like this

<!--listener>
    <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
</listener-->

<filter>
    <filter-name>webContextFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>webContextFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

I commented out the JBoss SpringContextLoaderListener above to avoid an IllegalStateException because I am using a subclass of AbstractSecurityWebApplicationInitializer elsewhere (from a mandatory library) which itself creates the root application context.

When I run this under tomcat7, I get a

SEVERE: Exception starting webContextFilter org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'webContextFilter' is defined

The applicationContext.xml contains the appropriate component-scan definitions, so that's not the problem.

I am guessing maybe the context loader from AbstractSecurityWebApplicationInitializer is not yet started when DelegatingFilterProxy is created??

How can I fix this?

EDIT1: The webContextFilter bean is in the right package, i.e. subpackage of the one listed in context:component-scan, and the bean is defined as

@Component("webContextFilter")
public class WebContextFilter extends OncePerRequestFilter {
// ...
}

The bean is in a WEB-INF/lib/xyz.jar. This all used to work under tomcat6 when the JBoss resteasy SpringContextLoaderListener was uncommented in web.xml.

EDIT2: Perhaps my question boils down to this: when using AbstractSecurityWebApplicationInitializer to create the root context, how do I specify additional filters, since the ones in web.xml don't seem to work?

回答1:

DelegatingFilterProxy is a proxy that delegates to spring managed bean. name of a bean that should be registered in container is webContextFilter in your case. Bean should implement Filter interface. This excerpt is taken from javadoc of DelegatingFilterProxy

Proxy for a standard Servlet 2.3 Filter, delegating to a Spring-managed * bean that implements the Filter interface. Supports a "targetBeanName" * filter init-param in {@code web.xml}, specifying the name of the * target bean in the Spring application context. * *

{@code web.xml} will usually contain a {@code DelegatingFilterProxy} definition, * with the specified {@code filter-name} corresponding to a bean name in * Spring's root application context. All calls to the filter proxy will then * be delegated to that bean in the Spring context, which is required to implement * the standard Servlet 2.3 Filter interface. * *

This approach is particularly useful for Filter implementation with complex * setup needs, allowing to apply the full Spring bean definition machinery to * Filter instances. Alternatively, consider standard Filter setup in combination * with looking up service beans from the Spring root application context.

If you have this bean in your context, then please update your question with bean declaration and tell number of containers you're using



回答2:

The problem was that the applicationContext.xml was not being read, so I added @ImportResource annotation to the SecurityConfig class definition.

@Configuration
@ImportResource("/WEB-INF/applicationContext.xml")
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
}