문자열 값에서 자리 표시자를 확인할 수 없습니다.


88

.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이 다음 예외를 throw합니다.

    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>

나는 분명히 뭔가를 놓치고 있지만 무엇을 알 수 없습니다.

더 자세한 정보가 필요하면 알려주세요. 첫 번째 질문이므로 최대한 빨리 답변 해 드리겠습니다. :).


1
어디에 infraContext.xml적재되고 있습니까? 스택 트레이스에서 판단하면 ContextLoaderListener. web.xml을 게시하십시오.
M. Deinum 2013

2
문제는 PropertySourcesPlaceholderConfigurer하나의 인스턴스가 명시 적으로 정의되어 있고 (왜?) 네임 스페이스로 인해 하나의 인스턴스가 있다는 것입니다. 당신의 사람 applicationContext.xml은 아무것도하지 않고 아무것도 추가하지 않습니다. 그것을 제거하십시오.
M. Deinum 2013

답변:


74

구성에는 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"/>

기본적으로 a PlaceholderConfigurer는 fail-fast이므로 자리 표시자를 확인할 수없는 경우 예외가 발생합니다. applicationContext.xml파일 의 인스턴스 에는 속성이 없으므로 모든 자리 표시 자에서 실패합니다.

해결 방법 : applicationContext.xml 에서 하나를 제거하십시오. 아무것도 추가하지 않기 때문에 문제가 발생할뿐입니다.


훌륭합니다. 감사합니다. Spring에는 PlaceholderConfigurer?의 인스턴스가 하나만있을 수 있다고 생각합니다 .
Mushtaq Jameel

11
아니요, 여러 개를 가질 수 있지만 기본적으로 자리 표시자를 찾지 못하면 빠르게 실패합니다. 로 설정 ignore-unresolved-placeholders하여 비활성화 할 수 있습니다 true.
M. Deinum 2015 년

3
주석으로 스프링 부트에서 어떻게 처리 할 수 ​​있습니까?
rezKesh

5

나는 같은 문제가 있었고 추가하여 해결했습니다.

<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을 실행 하고 응용 프로그램을 배포하십시오.


고마워, 내 문제가 해결되었습니다. 나는 왜 / 어떻게 maven 리소스 플러그인이 스프링 자리 표시 자에 영향을 미치는지 궁금합니다.
Pim Hazebroek

3

이 문제는 애플리케이션이 some_file_name.properties 파일에 접근 할 수없는 경우 발생하며, Spring에서 properties 파일이 resources 폴더 아래에 있는지 확인하십시오.

문제 해결 단계

1 : 리소스 폴더 아래에 속성 파일을 추가합니다.

2 : 리소스 폴더가없는 경우. 프로젝트 새로 만들기> 소스 폴더를 마우스 오른쪽 버튼으로 클릭하여 새 항목을 탐색하여 새로 만들고 리소스 이름을 지정한 다음 속성 파일을 그 아래에 놓습니다.

주석 기반 구현 용

더하다 @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

1
이것은 Spring4 이상에 적용됩니까?
Malkocoglu

예 @Malkocoglu
가니

3

제 경우에는 application.yml 파일을 병합하는 동안 부주의했고 오른쪽에 속성을 불필요하게 들여 쓰기했습니다.

다음과 같이 들여 쓰기했습니다.

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

코드는 다음과 같을 것으로 예상했지만 :

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

3

기본값을 사용해 볼 수도 있습니다. 스프링 값 주석

정의되지 않은 속성에 대해 기본값을 제공 할 수 있습니다. 이 예에서는 "some default"값이 삽입됩니다.

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

동일한 속성이 시스템 속성과 속성 파일에 정의되어 있으면 시스템 속성이 적용됩니다.


좋아요 ...이게 도움이되었습니다. 실제로 내 앱에는 많은 application- <profile> .yml 파일이 있으며 기본 구성에 정의 된 새 속성으로 인해 오류가 발생했습니다. 파일 만. 솔직히 기본 구성에서 한 번만 값을 정의하고 프로필 별 구성에서 값을 재정의 할 것으로 예상했습니다. 그렇게 작동하지 않는 것 같으며 항상 기본값을 제공해야합니다. 이제 속성을 기본값으로 초기화하지 않았을 때 Java 구성이 실패한 이유를 이해했습니다! 이 동작을 변경할 수 있습니까? 감사합니다 :-)
funder7

3

프로그램에서 @Value 주석을 선언 할 때마다 내 마이크로 서비스에서 동일한 오류가 발생했습니다. 즉 @Value ( "$ {project.api.key}")

동일한 값을 가진 application.properties 파일이 비어 있지 않아야합니다. project.api.key = 일부 값 추가

MostIMP : 그렇지 않으면 " 'ServiceFTP'이름으로 빈 생성 오류 : 자동 연결 종속성 주입"오류가 발생합니다.


0

Spring Boot 사용 :

pom.xml에서

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

Java 클래스의 예

@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.properties

foo=all-env-foo

src / main / resources / application-rec.properties

bar=rec-bar

src / main / resources / application-prod.properties

bar=prod-bar

Application.java의 VM 인수에서

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

속성을 수정 한 후 mvn 명령을 실행하는 것을 잊지 마십시오!

mvn clean package -Dmaven.test.skip=true

-Dspring.profiles.active = rec에 대한 로그 파일에서 :

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

-Dspring.profiles.active = prod의 로그 파일에서 :

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

-Dspring.profiles.active = local에 대한 로그 파일에서 :

Could not resolve placeholder 'bar' in value "${bar}"

죄송합니다. application-local.properties를 만드는 것을 잊었습니다.


0

내 마이크로 서비스 프로젝트에서 동일한 오류가 발생했습니다. 속성 자체가 내 yml 파일에서 누락되었으므로 문제를 해결하는 속성 이름과 값을 추가했습니다.


0

이 오류는 스프링 프로젝트가 파일 속성 ( bootstrap.yml 또는 application.yml )을 읽지 않기 때문에 나타납니다 . 이 문제를 해결하려면 pom.xml 에 종속성을 추가해야합니다.

   <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-context</artifactId>
    </dependency>

0

미안 자주 사용 찾을 수 없습니다 일부 사용자 지정 속성에이 문제에 실행 하게 IntelliJ IDEA를 가능성이 후 - 가지 변화 .

제 경우에 도움이되는 것은

파일-> 캐시 무효화 / 다시 시작

IDE 문제보다 Gradle 캐싱 문제 일 가능성이 더 높다고 가정했지만 ./gradle clean 은 도움이되지 않았습니다.



-3

내 해결책은 $와 {사이에 공백을 추가하는 것이 었습니다.

예를 들면 :

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

된다

@Value("$ {project.ftp.adresse}")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.