Reputation: 1207
I have a servlet running and I am trying to inject a property-value into a Filter.
I am confident that the appConfig file is being loaded (when I change the file name, I get a FileNotFound exception). Same count for the properties-file.
It seems the class where I try to inject the property is somehow ignored by Spring. It is a filter (see below). I have experimented with this by adding the property value in the annotation itself. (@Value("${filter.weburl:'some'}"). However, the String webURL remains NULL.
Can anyone help me figure out what is going on here?
package example.servlet.filters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class AuthenticationFilter implements Filter{
private ServletContext context;
private final Logger LOGGER = LoggerFactory.getLogger(AuthenticationFilter.class);
@Value("${filter.weburl:'some'}")
private String webURL;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.context = filterConfig.getServletContext();
this.context.log("AuthenticationFilter initialized");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
Cookie[] cookies = request.getCookies();
if(cookies != null) {
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + " " + cookie.getValue() + "\n");
}
} else {
((HttpServletResponse)servletResponse).sendRedirect(webURL + "/inloggen");
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
My AppConfig file:
package example;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
@Configuration
@ComponentScan("example")
@PropertySource("WEB-INF/service.properties")
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public FilterRegistrationBean authenticationFilterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(getAuthenticationFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.setName("authenticationFilter");
filterRegistrationBean.setOrder(1);
return null;
}
@Bean(name="authenticationFilter")
public AuthenticationFilter getAuthenticationFilter() {
return new AuthenticationFilter();
}
}
Upvotes: 4
Views: 1976
Reputation: 1938
Had the same issue and none of the answers on SE worked for me. The only thing that worked was to replace field injection with method argument injection, i.e. instead of
@Configuration
public class MyConfig {
@Value("${jdbc.hibernate.dialect}")
private String dialect;
@Value("${jdbc.hibernate.show_sql}")
private String showSql;
@Bean
public SessionFactory sessionFactory(DataSource dataSource) {
...
}
}
used this
@Configuration
public class MyConfig {
@Bean
public SessionFactory sessionFactory(DataSource dataSource,
@Value("${jdbc.hibernate.dialect}") String dialect,
@Value("${jdbc.hibernate.show_sql}") String showSql) {
...
}
}
Note that the first argument (dataSource) was correctly injected in both cases, only the properties were not.
Upvotes: 0
Reputation: 51441
If you register a filter in the Application Context it will be registered for all requests, if you use a FilterRegistrationBean, you can customize the URL paths that the filter applies to. You seem to have both and it's probably causing all sorts of problems. Also your filter is annotate with @Component
AND you're creating the filter as a bean in your configuration class.
This is how you should structure your code to make it work:
// No @Component annotation keeps this class pure as you're using your configuration class to create beans
public class AuthenticationFilter implements Filter{
private ServletContext context;
private final Logger LOGGER = LoggerFactory.getLogger(AuthenticationFilter.class);
private String webURL;
public AuthenticationFilter(String webURL) {
this.webURL = webURL;
}
// rest of filter
}
Configuration class:
@Configuration
@ComponentScan("example") //if you have other components to scan, otherwise not required
@PropertySource("WEB-INF/service.properties")
public class AppConfig {
@Value("${filter.weburl:some}")
String webURL;
@Bean
public static PropertySourcesPlaceholderConfigurer getPropertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
public FilterRegistrationBean authenticationFilterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new AuthenticationFilter(this.webURL));
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.setName("authenticationFilter");
filterRegistrationBean.setOrder(1);
return filterRegistrationBean;
}
}
Upvotes: 1
Reputation: 8386
You need to have following in your configuration class.
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
To configure filter using web.xml do this
<filter>
<filter-name>authenticationFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>authenticationFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Upvotes: 1