Spring Boot无法解析字符串中的占位符。

35

我正在使用Maven通过mvn clean install spring-boot:run命令在嵌入式Tomcat服务器上运行Spring Boot。但每次运行时,我都会遇到以下错误:

 Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'language' in string value "${language}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:172) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:831) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1086) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE]
    ... 35 common frames omitted

那个错误与这两行代码有关:

@Value("${language}")
private String language;

那个语言标志在我的 application.properties 文件中是这样指定的:

application.properties


Translated:

That language flag is specified in my application.properties like this:

application.properties

language=java
logging.level.org.springframework=TRACE
这是令人困惑的部分:当我不使用spring-boot:run命令运行构建时,它可以成功构建,我可以毫无问题地运行构建的jar文件。只有当我尝试在嵌入的Tomcat服务器上运行时才会遇到此问题。

我可以通过在我的代码中这样做来绕过这个问题:

@Value("${language:java}")
private String language;

但是这对我来说没有意义,因为春季应该自动从application.properties文件中读取默认值。

编辑:如一些人所指出的那样,在内嵌式tomcat服务器上运行时根本没有读取application.properties。 有没有办法强制它去读取文件,或者可能不读取文件的原因? 在部署到外部应用程序服务器而不是嵌入式服务器时,它可以正常工作。


你确定你的嵌入式Tomcat看到了属性文件并加载了它吗? - tsolakp
是的 - 看起来它没有读取属性文件。但我不确定为什么。当部署在外部Tomcat服务器上或作为Java应用程序运行时,它可以读取它,所以这让我感到困惑。 - Karan
1
我遇到了完全相同的问题,但情况正好相反。在我的情况下,我在application.properties中设置了logging.file.name=${log_dir},而在Liberty server.env文件中设置了log_dir=C:\mydir"。如果我在Liberty服务器上运行它,我会得到相同的错误。我发现唯一解决它的方法是在我的*application.properties*中硬编码设置,如logging.file.name=C:\mydir```。但这当然不是最好的解决方案。 - pixel
13个回答

40

通过在<resources>部分下添加这些行进行修复

<resource>
     <directory>src/main/resources</directory>
     <filtering>true</filtering>
     <includes>
          <include>**/*.properties</include>
     </includes>
</resource>

我不完全理解这样做的必要性。

a)我可以在外部应用程序服务器上运行此项而不必添加此行,应用程序可以正常读取application.properties

b)我可以在Eclipse中作为独立的Java应用程序运行该应用程序(即,无需通过maven构建应用程序),并且它可以正常读取application.properties

c)不是Spring Boot默认就可以读取它吗? (如上述两种情况所示?)

感谢大家的帮助。希望这可以帮助其他人。


2
我猜想你的pom.xml中没有继承spring-boot-starter-parent。 - user1455836
1
由于某种原因,**/* 对我不起作用,所以我不得不添加 <directory>src/main/resources/config</directory> 来处理位于 config 目录下的文件。 - Archmede
这是正确的,但是为了将其部署为远程服务器上的JAR文件,我们需要从JAR文件中排除属性文件。因此,像这样包含它们会破坏拥有属性文件的目的。您能对此发表评论吗?我已经在build->resources->excludes标签下明确地将它们排除了。 - u tyagi

21

当我在 IntelliJ 中运行时,我也遇到了类似的问题。 下面是解决方法: Build -> Rebuild Project。


12

我在IntelliJ上遇到了同样的问题。通过File -> Invalidate Caches / Restart ...来使缓存失效,它为我解决了这个问题。


7

我不明白为什么这个有效,但是谢谢! - Arthur Champs
这对我起了作用,如果您有多个 .properties 文件,请添加 :default - Cipher
将默认设置为这样意味着硬编码它。在许多情况下,您不希望这样做,例如,files.root的值可能会因环境而异,如果您不想将其值保留在application.property中,则不希望将其公开给每个人一旦推送到repo。因此,您可能希望此值直接来自服务器/容器,并在application.properties中访问它,如files.root = $ {files_root}files_root可以在服务器env文件中设置,但在这种情况下,由于某种原因,它将无法使用@Value解析。 - pixel

5

你是否尝试在Eclipse中运行此项任务?

我曾经遇到过同样的问题,并发现该项目没有Maven性质。右键单击该项目->配置->转换为Maven项目。然后再次右键单击该项目->Maven->更新项目即可解决该问题。


3

在我的情况下,在IntelliJ中,我使用了一个不同的配置文件。 因此,在我的情况下选择dev配置文件解决了一个问题。


3

我和你有类似的问题,我通过以下方式解决:

在你的 pom.xml 中,如果你有多个配置文件或属性,请选择一个默认选中的配置文件。

<profiles>
        <profile>
            <id>dev</id>
            <properties>
                <activatedProperties>dev</activatedProperties>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <profile>
            <id>prod</id>
            <properties>
                <activatedProperties>prod</activatedProperties>
            </properties>
        </profile>
    </profiles>

接着进入你的application.properties文件,插入以下代码

spring.profiles.active=@activatedProperties@

2
我缺少以下的依赖。
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

我需要读取通用配置服务器的配置值。

在我的情况下,当我收到“无法解析占位符”的消息时,尽管它存在于配置服务中 - 添加此依赖项解决了问题。另外,我添加了-Dspring.cloud.bootstrap.enabled=true来运行脚本。 - Kirill Mikhailov

1
如果您已经正确设置了值,请检查您的资源文件夹是否被IDE标识为“resources”。在IntelliJ中,您可以右键单击资源并选择“标记为资源根目录”。

1

我也遇到了这个问题。在我的情况下,问题是由于我将值放在错误的文件中引起的。 错误的文件路径为: BIN/src/main/resource/application.properties 正确的文件路径应该是: src/main/resource/application.properties


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接