无法解析字符串值中的占位符

时间:2013-11-27 14:10:50

标签: java spring

我正在尝试使用.properties文件中的属性,但它似乎不起作用。

这是我的代码:

@Service("ServiceFTP")
@Transactional
public class ServiceFTPImpl implements ServiceFTP {

@Value("${project.ftp.adresse}")
private String adresse;

@Value("${project.ftp.login}")
private String compte;

@Value("${project.ftp.password}")
private String motDePasse;

@Value("${project.ftp.root}")
private String ROOT;

[...]

}

此类使用@Value注释来获取属性。 它也被声明为Spring Service并链接到我的infraContext.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

<context:property-placeholder location="classpath:context-core.properties"/>

[...]

</beans>

使用context:property-placeholder,我将此文件链接到我的context-core.properties文件:

project.ftp.adresse = localhost
project.ftp.login = anonymous
project.ftp.password =
project.ftp.root = /anonymous/

这确实有道理,对吧?

但是当我尝试启动我的项目时,Tomcat抛出了这个异常:

    ERROR [context.ContextLoader.initWebApplicationContext()] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ServiceFTP': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String project.sins.service.impl.ServiceFTPImpl.adresse; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'project.ftp.adresse' in string value "${project.ftp.adresse}"
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:925)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:472)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:388)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4887)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5381)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
    at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:657)
    at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1636)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String project.sins.service.impl.ServiceFTPImpl.adresse; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'project.ftp.adresse' in string value "${project.ftp.adresse}"
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:513)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:92)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    ... 27 more
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'project.ftp.adresse' in string value "${project.ftp.adresse}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:173)
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:125)
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:151)
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:142)
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:169)
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:748)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:740)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:485)
    ... 29 more

或者,简而言之:java.lang.IllegalArgumentException: Could not resolve placeholder 'project.ftp.adresse' in string value "${project.ftp.adresse}"

编辑:

这是我的web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="sins" version="2.5">

    <display-name>Project</display-name>

    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <context-param>
        <param-name>log4jExposeWebAppRoot</param-name>
        <param-value>false</param-value>
    </context-param>

    <filter>
        <filter-name>ExpiresFilter</filter-name>
        <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
        <init-param>
            <param-name>ExpiresByType text/html</param-name>
            <param-value>now plus 0 seconds</param-value>
        </init-param>
        <init-param>
            <param-name>ExpiresByType application/json</param-name>
            <param-value>now plus 0 seconds</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>ExpiresFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
        <filter-class>
            org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.apache.struts2.tiles.StrutsTilesListener</listener-class>
    </listener>

    <context-param>
        <param-name>
            org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
        </param-name>
        <param-value>
            /WEB-INF/tiles/user.xml
        </param-value>
    </context-param>

    <resource-ref>
        <res-ref-name>jdbc/si_nsg</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>

    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>

</web-app>

我的infraContext.xml导入另一个名为applicationContext.xml的.xml文件中:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">

    <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="environment">
            <bean class="org.springframework.web.context.support.StandardServletEnvironment"/>
        </property>
    </bean>

    <import resource="classpath:securityContext.xml"/>

    [...]
    <import resource="classpath:project/sins/persistenceContext.xml"/>

    <import resource="classpath:project/sins/infraContext.xml"/>

</beans>

我显然缺少一些东西,但我无法弄清楚是什么。

如果您需要更多详细信息,请告诉我,因为这是我的第一个问题,我会尽快回答:)。

16 个答案:

答案 0 :(得分:61)

在您的配置中,您有2个PropertySourcesPlaceholderConfigurer个实例。

的applicationContext.xml

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="environment">
        <bean class="org.springframework.web.context.support.StandardServletEnvironment"/>
    </property>
</bean>

infraContext.xml

<context:property-placeholder location="classpath:context-core.properties"/>

默认情况下,PlaceholderConfigurer将失败,因此如果占位符无法解析,则会抛出异常。 applicationContext.xml文件中的实例没有属性,因此在所有占位符上都会失败。

解决方案:从 applicationContext.xml 中删除一个,因为它不会添加任何只会破坏的内容。

答案 1 :(得分:3)

您也可以尝试使用默认值。 spring-value-annotation

可以为可能未定义的属性提供默认值。在此示例中,将注入“一些默认值”值:

@Value("${unknown.param:some default}")
private String someDefault;

如果在属性文件中将相同的属性定义为系统属性,则将应用系统属性。

答案 2 :(得分:3)

每当您在程序中声明@Value注释,即 @Value(“ $ {project.api.key}”)时,我的微服务中都会出现相同的错误

确保具有相同值的application.properties文件不应为空白 project.api.key =添加一些值

MostIMP :否则它将引发错误“创建名称为'ServiceFTP'的bean时出错:自动连接依赖项的注入”

答案 3 :(得分:2)

我遇到了同样的问题,通过添加

解决了这个问题
<filtering>true</filtering> 

在pom.xml中:

之前(不起作用):

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>               
        </resource>
    </resources>
</build>

之后(工作):

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

之后,您只需运行 mvn clean install 并部署应用程序。

答案 4 :(得分:1)

如果应用程序无法访问some_file_name.properties文件,则会发生此问题。请确保在春季将属性文件放置在resources文件夹下。

故障排除步骤

1:将属性文件添加到资源文件夹下。

2:如果没有资源文件夹。通过右键单击new来创建新文件,方法是:右键单击project new> Source Folder,将其命名为资源,然后将属性文件放置在它下面。

用于基于注释的实施

添加@PropertySource(ignoreResourceNotFound = true, value = "classpath:some_file_name.properties") //在使用占位符之前添加

示例:

Assignment1Controller.Java

@PropertySource(ignoreResourceNotFound = true, value = "classpath:assignment1.properties")
@RestController  
public class Assignment1Controller {

//  @Autowired
//  Assignment1Services assignment1Services;
    @Value("${app.title}")
    private String appTitle;
     @RequestMapping(value = "/hello")  
        public String getValues() {

          return appTitle;

        }  

}

assignment1.properties

app.title=Learning Spring

答案 5 :(得分:1)

就我而言,合并application.yml文件时我很粗心,而且我不必要在右边缩进属性。

我已经像这样缩进了

spring:
    application:
       name: applicationName
............................
    myProperties:
       property1: property1value

代码期望它像这样:

spring:
    application:
        name: applicationName
.............................
myProperties:
    property1: property1value

答案 6 :(得分:1)

我在 Spring Boot 应用程序中遇到了类似的问题。

在主应用程序SCR目录下的application.properties文件中添加属性配置时,请确保对test目录下的application.properties文件进行同样的操作。

答案 7 :(得分:1)

将相同的属性添加到 application.properties 会很有帮助。

答案 8 :(得分:0)

使用Spring Boot:

在pom.xml中

gcloud container clusters create hello-server 
gcloud container clusters get-credentials hello-server

kubectl create deployment hello-server \
--image=gcr.io/google-samples/hello-app:1.0

kubectl expose deployment hello-server \
--type LoadBalancer \
--port 80 \
--target-port 8080

kubectl get  nodes

Java类中的示例

NAME                                          STATUS   ROLES    AGE   VERSION
gke-hello-server-default-pool-03b44665-5grf   Ready    <none>   48m   v1.13.7-gke.24
gke-hello-server-default-pool-03b44665-65j5   Ready    <none>   48m   v1.13.7-gke.24
gke-hello-server-default-pool-03b44665-ng8w   Ready    <none>   48m   v1.13.7-gke.24


$kubectl get pods

NAME                            READY   STATUS    RESTARTS   AGE
hello-server-64db4d4dc7-llr5t   1/1     Running   0          29m

在属性文件中:

src / main / resources / application.properties

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <addResources>true</addResources>
            </configuration>
        </plugin>
    </plugins>
</build>

src / main / resources / application-rec.properties

@Configuration
@Slf4j
public class MyAppConfig {
    @Value("${foo}")
    private String foo;
    @Value("${bar}")
    private String bar;
    @Bean("foo")
    public String foo() {
        log.info("foo={}", foo);
        return foo;
    }
    @Bean("bar")
    public String bar() {
        log.info("bar={}", bar);
        return bar;
    }
    [ ... ]

src / main / resources / application-prod.properties

foo=all-env-foo

在Application.java的VM参数中

bar=rec-bar

不要忘记在修改属性后运行mvn命令!

bar=prod-bar

在-Dspring.profiles.active = rec的日志文件中:

-Dspring.profiles.active=[rec|prod]

-Dspring.profiles.active = prod的日志文件中:

mvn clean package -Dmaven.test.skip=true

-Dspring.profiles.active = local的日志文件中:

The following profiles are active: rec
foo=all-env-foo
bar=rec-bar

糟糕,我忘了创建application-local.properties。

答案 9 :(得分:0)

我在微服务项目中遇到了同样的错误.yml文件中缺少属性本身,因此我添加了解决问题的属性名称和值

答案 10 :(得分:0)

出现此错误是因为spring项目无法读取文件属性( bootstrap.yml application.yml )。为了解决此问题,您必须在 pom.xml

中添加依赖项
   <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-context</artifactId>
    </dependency>

答案 11 :(得分:0)

我经常在一些使用 IntelliJ IDEA 无法找到的自定义属性上遇到此问题 - 可能是在更改分支之后。

对我来说有帮助的是

<块引用>

文件 -> 使缓存无效/重新启动

我假设它更可能是 Gradle 缓存问题而不是 IDE 问题,但是 ./gradle clean 没有帮助

答案 12 :(得分:0)

就我而言,我在从 eclipse 运行时遇到了同样的问题。只是做了以下来解决它: 右键单击项目 --> Mavan --> 更新项目。

它奏效了!

答案 13 :(得分:0)

我刚刚在我的测试文件夹的 application.xml 文件中添加了属性的配置,就像在我的 SRC 文件夹中一样,它解决了我的问题。

答案 14 :(得分:-1)

我的解决方案是在$和{之间添加一个空格。

例如:

@Value("${project.ftp.adresse}")

成为

@Value("$ {project.ftp.adresse}")

答案 15 :(得分:-1)

删除或破坏pom.xml文件会导致此错误。