【问题标题】:@Value does not inject property, stays null@Value 不注入属性,保持为空
【发布时间】:2017-02-27 10:59:18
【问题描述】:

我有一个 servlet 正在运行,我正在尝试将一个属性值注入到过滤器中。

我确信 appConfig 文件正在加载(当我更改文件名时,我收到 FileNotFound 异常)。属性文件的计数相同。

似乎我尝试注入属性的类被 Spring 以某种方式忽略了。它是一个过滤器(见下文)。我已经通过在注释本身中添加属性值来对此进行试验。 (@Value("${filter.weburl:'some'}")。但是,字符串 webURL 仍然为 NULL。

谁能帮我弄清楚这里发生了什么?

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() {

    }
}

我的 AppConfig 文件:

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();
    }
}

【问题讨论】:

  • 你的过滤器其实也是spring bean?基本上,该字段不能为null,如果无法解析,它将回退到您提供的默认值。由于它没有这样做,我怀疑您使用的过滤器实例是 Spring 已知的实例。
  • 您是否尝试将应该由@Value 填充的字段设置为公开?

标签: java spring servlets


【解决方案1】:

你需要在你的配置类中有以下内容。

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

要使用 web.xml 配置过滤器,请执行此操作

<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>

【讨论】:

  • 我应该将此添加到我的问题中,但它已经存在:-)。我已经编辑了我的问题以澄清这一点。
  • 您是如何注册过滤器的?你能分享那个代码吗?
  • 在这里查看我的答案stackoverflow.com/questions/42176625/…
  • 所以我通过 web.xml 注册了我的过滤器。我已经从这里删除了它并使用了 Springboot FilterRegistrationBean。但是,完成此操作后,我现在得到了 NoClassDefFoundError。 (我将在几秒钟内编辑我的第一篇文章以添加我的新配置)。问题可能是由于其他过滤器仍然通过 web.xml 注册的事实吗?
  • 如果您使用的是 Spring Boot,@RobertvanderSpek FilterRegistrationBean 绝对足够了。绝对不需要有web.xml 文件。
【解决方案2】:

如果您在应用程序上下文中注册过滤器,它将为所有请求注册,如果您使用 FilterRegistrationBean,您可以自定义过滤器应用到的 URL 路径。你似乎两者都有,它可能会导致各种问题。此外,您的过滤器使用 @Component 进行注释,并且您正在将过滤器创建为配置类中的 bean。

这是您应该如何构建代码以使其工作:

// 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
@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;
    }
}

【讨论】:

    【解决方案3】:

    遇到了同样的问题,SE 上的所有答案都没有对我有用。唯一有效的方法是用方法参数注入替换字段注入,即代替

    @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) {
           ...
        }
    }
    

    用过这个

    @Configuration
    public class MyConfig  {
    
        @Bean
        public SessionFactory sessionFactory(DataSource dataSource,
                @Value("${jdbc.hibernate.dialect}") String dialect,
                @Value("${jdbc.hibernate.show_sql}") String showSql) {
            ...
        }
    }
    

    请注意,第一个参数(dataSource)在两种情况下都被正确注入,只有属性没有。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-19
      • 2011-11-17
      • 1970-01-01
      • 2011-10-31
      • 1970-01-01
      • 2020-10-22
      • 1970-01-01
      • 2022-06-22
      相关资源
      最近更新 更多