I\'m programming a Tomcat application which serves as a proxy for some internal services.
I\'ve switched my Spring project from a mixed XML and annotation-based conf
As the application context is correctly injected in your controller, I assume that Spring is correctly initialized. But your filters are declared as raw filters, not as spring beans, so the spring annotations are ignored on them.
You have two ways to get access to the application context:
a raw filter (not Spring enabled) can get access to the root application context with WebApplicationContext WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)
. For example, you could change your init
method:
@Override
public void init(FilterConfig filterConfig)
{
ServletContex sc = filterConfig.getServletContext();
appContext = WebApplicationContextUtils.getWebApplicationContext(sc);
logger.debug("Filter {} initialisiert. App-Context: {} {}", this.getClass().getName(),appContext.hashCode(), appContext);
}
you can also use a DelegatingFilterProxy
to effectively use beans as filters:
Change add filter to:
private void addFilters(ServletContext container) {
FilterRegistration.Dynamic registration
= container.addFilter("u3rAuthentication", DelegatingFilterProxy.class);
registration.addMappingForUrlPatterns(null, false, "/entry/*");
registration = container.addFilter("responseXmlFilter", DelegatingFilterProxy.class);
registration.addMappingForUrlPatterns(null, false, "/entry/*");
}
add filter beans in your root context:
@Bean
public UserDbAuthenticationFilter u3rAuthentication() {
return new UserDbAuthenticationFilter();
}
@Bean
public ResponseTextXmlFilter responseXmlFilter() {
return new ResponseTextXmlFilter();
}
the init method will no longer be called, but this would work:
@PostConstruct
public void filterInit() throws ServletException
{
logger.debug("Filter {} initialisiert. App-Context: {} {}", this.getClass().getName(),appContext.hashCode(), appContext);
}
The culprit is addFilter(..)
method of MyAppSpringBoot
.
If you look closely at this LOC FilterRegistration.Dynamic registration = container.addFilter("u3rAuthentication", UserDbAuthenticationFilter.class);
it will be evident that even though the UserDbAuthenticationFilter
is registered with ServletContext
as filter, it is not associated with spring context in any way (since the class is directly registered and not the spring bean which will explain the null
references of ApplicationContext
and emf
respectively).
Although same class UserDbAuthenticationFilter
is scanned by spring and registered as bean later but is not associated with ServletContext
as filter (this bean is never invoked as it is not registered as filter and this is where you see your ApplicationContext
being set while debugging)
So there are two instances for same class UserDbAuthenticationFilter
one as filter with servlet and another as spring bean with no association / link with each other.
What you need here is a filter registered with servlet container which is a spring bean as well. GenericFilterBean comes to your rescue. Extend it as per your need and be aware of the below gotcha (from API docs)
This generic filter base class has no dependency on the Spring ApplicationContext concept. Filters usually don't load their own context but rather access service beans from the Spring root application context, accessible via the filter's ServletContext (see WebApplicationContextUtils).
Hope this helps. Let know in comments in case you face any issues / need further help.