Impossibile risolvere il segnaposto nel valore di stringa


88

Sto cercando di utilizzare le proprietà da un .propertiesfile, ma non sembra funzionare.

Ecco il mio codice:

@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;

[...]

}

Questa classe utilizza le @Valueannotazioni per ottenere le proprietà. È anche dichiarato come Spring Service ed è collegato al mio infraContext.xmlfile:

<?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>

Utilizzando context:property-placeholder, collego questo file al mio context-core.propertiesfile:

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

Questo ha senso, vero?

Ma quando provo ad avviare il mio progetto, Tomcat genera questa eccezione:

    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

Oppure, in breve: java.lang.IllegalArgumentException: Could not resolve placeholder 'project.ftp.adresse' in string value "${project.ftp.adresse}"

MODIFICARE :

Ecco il mio 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>

Il mio infraContext.xml viene importato in un altro file .xml denominato 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>

Ovviamente mi manca qualcosa, ma non riesco a capire cosa.

Per favore fatemi sapere se avete bisogno di maggiori dettagli, dato che è la mia prima domanda qui, cercherò di rispondere il prima possibile :).


1
Dove viene infraContext.xmlcaricato? A giudicare dallo stacktrace non è incluso nella configurazione caricata dal ContextLoaderListener. Pubblica il tuo web.xml.
M. Deinum

2
Il problema è che hai più istanze di una PropertySourcesPlaceholderConfigurerdefinita esplicitamente (perché?) E una dovuta allo spazio dei nomi. Quello nel tuo applicationContext.xmlnon sta facendo niente né aggiunge niente. Rimuoverla.
M. Deinum

Risposte:


74

Nella tua configurazione hai 2 PropertySourcesPlaceholderConfigureristanze.

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"/>

Per impostazione predefinita, PlaceholderConfigurera fallirà rapidamente, quindi se un segnaposto non può essere risolto, verrà generata un'eccezione. L'istanza del applicationContext.xmlfile non ha proprietà e come tale avrà esito negativo su tutti i segnaposto.

Soluzione: rimuovi quello da applicationContext.xml poiché non aggiunge nulla, ma solo rompe le cose.


Fantastico, grazie, quindi presumo che in primavera possa esserci solo un'istanza di PlaceholderConfigurer?
Mushtaq Jameel

11
No, puoi averne più, ma per impostazione predefinita falliscono velocemente se non viene trovato un segnaposto. Puoi disabilitarlo impostando ignore-unresolved-placeholderssu true.
M. Deinum

3
come posso gestirlo in avvio di primavera con annotazioni?
rezKesh

5

Ho avuto lo stesso problema, risolto aggiungendo

<filtering>true</filtering> 

in pom.xml:

prima (non funzionava):

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

dopo (ha funzionato):

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

Dopodiché, esegui mvn clean install e distribuisci l'applicazione.


Grazie, questo ha risolto il mio problema. Sono curioso però, perché / come il plug-in delle risorse di Maven influisce sui segnaposto primaverili ... Non avrei mai immaginato che fossero correlati!
Pim Hazebroek

3

Questo problema si verifica se l'applicazione non è in grado di accedere al file some_file_name.properties file. Assicurati che il file delle proprietà sia posizionato nella cartella delle risorse in primavera.

Procedura di risoluzione dei problemi

1: aggiungi il file delle proprietà nella cartella delle risorse.

2: se non hai una cartella delle risorse. Creane uno navigando in nuovo facendo clic con il pulsante destro del mouse sul progetto nuovo> Cartella sorgente, nominalo come risorsa e posiziona il tuo file delle proprietà sotto di esso.

Per l'implementazione basata sull'annotazione

Aggiungi @PropertySource(ignoreResourceNotFound = true, value = "classpath:some_file_name.properties")// Aggiungilo prima di utilizzare il segnaposto

Esempio:

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
Questo vale per Spring4 e versioni successive?
Malkocoglu

Sì @Malkocoglu
Gani

3

Nel mio caso, sono stato distratto durante l'unione del file application.yml e non ho indennizzato le mie proprietà a destra.

L'ho indentato in questo modo:

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

Mentre il codice si aspettava che fosse così:

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

3

Puoi anche provare i valori predefiniti. annotazione-valore-molla

È possibile fornire valori predefiniti per proprietà che potrebbero non essere definite. In questo esempio verrà inserito il valore "some default":

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

Se la stessa proprietà è definita come proprietà di sistema e nel file delle proprietà, verrà applicata la proprietà di sistema.


Ok ... questo mi ha aiutato. In effetti la mia app ha molti file application- <profile> .yml e stavo ricevendo un errore a causa di una nuova proprietà definita nella configurazione principale. solo file. Onestamente mi aspettavo di definire il valore solo una volta nella configurazione principale e, nel caso, sovrascrivere il valore in una configurazione specifica del profilo. Sembra che non funzioni in questo modo e deve essere sempre fornito un valore predefinito. Ora capisco perché le mie configurazioni java non funzionavano, quando non inizializzavo le proprietà con un valore predefinito! Può essere cambiato questo comportamento? Grazie :-)
funder7

3

Ho lo stesso errore nel mio Micro-servizio, ogni volta che dichiari l'annotazione @Value nel programma, ad es @Value ("$ {project.api.key}")

assicurati che il tuo file application.properties con gli stessi valori non debba essere vuoto project.api.key = aggiungi alcuni valori

MostIMP : altrimenti verrà generato l'errore "Errore durante la creazione del bean con nome" ServiceFTP ": inserimento di dipendenze cablate automaticamente"


0

Con Spring Boot:

Nel file pom.xml

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

Esempio in classe 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;
    }
    [ ... ]

Nei file delle proprietà:

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

Negli argomenti VM di Application.java

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

Non dimenticare di eseguire il comando mvn dopo aver modificato le proprietà!

mvn clean package -Dmaven.test.skip=true

Nel file di registro per -Dspring.profiles.active = rec:

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

Nel file di registro per -Dspring.profiles.active = prod:

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

Nel file di registro per -Dspring.profiles.active = local:

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

Oups, ho dimenticato di creare application-local.properties.


0

Ho ricevuto lo stesso errore nel mio progetto di microservizio: la proprietà stessa non era presente nel mio file yml, quindi ho aggiunto il nome e il valore della proprietà che risolvono il mio problema


0

Questo errore appare perché il progetto Spring non legge le proprietà del file ( bootstrap.yml o application.yml ). Per risolvere questo problema, devi aggiungere la dipendenza nel tuo pom.xml

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

0

Mi imbatto spesso in questo problema su alcune proprietà personalizzate che non è stato possibile trovare utilizzando IntelliJ IDEA , probabilmente dopo aver modificato i rami .

Ciò che aiuta nel mio caso è

File -> Invalidate Caches / Restart

Pensavo che fosse più probabile un problema di memorizzazione nella cache di Gradle che un problema di IDE, ma ./gradle clean non ha aiutato



-3

La mia soluzione era aggiungere uno spazio tra $ e {.

Per esempio:

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

diventa

@Value("$ {project.ftp.adresse}")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.