【问题标题】:Spring Boot 2 can't read property as StringSpring Boot 2 无法将属性读取为字符串
【发布时间】:2019-05-18 10:00:01
【问题描述】:

在将 Spring Boot 应用程序从 Spring Boot 1.4.0 迁移到 Spring Boot 2 时,我开始在尝试从 .properties 文件中读取属性时遇到错误。

在属性文件中,属性定义为:

environment=dev

在我的一个课程中,我通过@Value 注释导入属性,如下所示:

@Getter
@Setter
public class CustomUserFilter extends SwitchUserFilter {
    ...
    @Value("${environment}")
    private String environment;
    ...

上面的类覆盖org.springframework.security.web.authentication.switchuser.SwitchUserFilter,使用户能够切换角色。

在 Spring Boot 1.4.0 之前,我能够在我的类中将此属性作为字符串导入。但是,自从迁移到 Spring Boot 2 后,我收到以下编译时错误:

错误:(43, 20) java: getEnvironment() in demo.config.CustomUserFilter 无法实现 getEnvironment() org.springframework.core.env.EnvironmentCapable 返回类型 java.lang.String 不兼容 org.springframework.core.env.Environment

我不确定为什么会这样。我也试过把这个变量的类型改成Environment (org.springframework.core.env.Environment)(如下图):

...
@Value("${environment}")
private Environment environment;
...

,但后来我开始收到以下错误:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'switchUserFilter': Unsatisfied dependency expressed through field 'environment'; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment': no matching editors or conversion strategy found
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:584)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:370)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1336)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:226)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:182)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:177)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:159)
    at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:81)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:261)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:185)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:154)
    ... 52 more
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:77)
    at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:60)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1089)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:581)
    ... 70 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:117)
    at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:70)
    ... 74 more

有什么线索可以说明什么问题吗?我正在使用 Spring Boot 2.0Spring 5Java 11Tomcat 8.5.35。谢谢!

【问题讨论】:

  • 在类声明上方添加@Configuration并检查它是否有效
  • Cannot convert value of type 'java.lang.String' to required type 'org.springframework.core.env.Environment' 似乎您在问题中遗漏了几行重要的代码。
  • MaruthiAdithya 我已经定义了一个单独的@Configuration 类,我尝试在其中初始化上述类的一个bean。但是我也尝试在这个类中添加它,没有奏效。
  • @DoNhuVy 我所做的就是从 private String environment; 更改为 private Environment environment;
  • 如果更改属性名称会怎样?

标签: java spring spring-boot


【解决方案1】:

该问题与 Spring Boot 无关。我上面的类扩展了org.springframework.security.web.authentication.switchuser.SwitchUserFilter,它进一步扩展了org.springframework.web.filter.GenericFilterBean。这个GenericFilterBean 类也有一个属性private Environment environment;。此外,这个类在 Spring 5 版本中被修改为在这个属性上包含一个 getter 方法。 Spring 5 在GenericFilterBean 类中引入了返回类型为EnvironmentgetEnvironment(),这与我的返回类型为StringgetEnvironment() 冲突。

为了避免这种冲突,我只是将我的属性名称从 environment 更改为 env,之后一切正常。

【讨论】:

  • 酷 - 感谢您发布解决方案。问:您的 Spring Boot 1.4.0 在哪个版本的 Spring 下运行。请“接受”你的回答。
  • @paulsm4 StackOverflow 显然不会让我在接下来的两天内接受。我正在使用 Spring Boot 1.4 运行 Spring 4.3.2。使用 Spring Boot 2.0 升级到 Spring 5.0.11。
  • 知道了。我认为您的变量与 Spring 3.1 中引入的新“环境”抽象之间可能存在名称冲突。
  • @paulsm4 是的,实际上不是environment 属性本身,而是它的getter。 Spring 5 引入了一个返回类型为 EnvironmentgetEnvironment(),这与我的返回类型为 StringgetEnvironment() 冲突。
【解决方案2】:

将@Component 添加到您的班级并尝试一下

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 2019-03-15
    • 2019-09-18
    相关资源
    最近更新 更多