Не удалось разрешить placeholder в строковом значении
Я пытаюсь использовать свойства из файла .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 и связан с моим файлом 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>
My infraContext.xml импортируется в другой XML файл с именем applicationContext.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
В вашей конфигурации у вас есть 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
будет работать с ошибкой, поэтому, если заполнитель не может быть разрешен, он выдает исключение. Экземпляр из файла applicationContext.xml
не имеет свойств и, как таковой, терпит неудачу на всех заполнителях.
Решение. Удалите файл из applicationContext.xml, поскольку он не добавляет ничего, что только ломает вещи.
Ответ 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 and deploy application.
Ответ 3
Эта проблема возникает, если приложение не может получить доступ к файлу some_file_name.properties. Убедитесь, что файл свойств помещен в папку ресурсов spring.
Действия по устранению неполадок
1. Добавьте файл свойств в папку ресурса.
2: если у вас нет папки ресурсов. Создайте его, перейдя по новой, щелкнув правой кнопкой мыши на проекте 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
Ответ 4
В моем случае я был небрежен при объединении файла application.yml, и у меня нет ненужных отступов в свойствах справа.
Я отступил так:
spring:
application:
name: applicationName
............................
myProperties:
property1: property1value
Хотя код ожидал, что это будет так:
spring:
application:
name: applicationName
.............................
myProperties:
property1: property1value
Ответ 5
Мое решение состояло в том, чтобы добавить пробел между $ и {.
Например:
@Value("${project.ftp.adresse}")
становится
@Value("$ {project.ftp.adresse}")
Ответ 6
С 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/основные/ресурсы/application.properties
foo=all-env-foo
SRC/основные/ресурсы/application-rec.properties
bar=rec-bar
SRC/основные/ресурсы/application-prod.properties
bar=prod-bar
В аргументах виртуальной машины Application.java
-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.