Fichier Spring .properties: obtenir l'élément sous forme de tableau

91

Je charge les attributs de propriétés à partir d'un .propertiesfichier à l'aide de Spring comme suit:

file: elements.properties
base.module.elementToSearch=1
base.module.elementToSearch=2
base.module.elementToSearch=3
base.module.elementToSearch=4
base.module.elementToSearch=5
base.module.elementToSearch=6

Le fichier XML Spring

file: myapplication.xml
<bean id="some"
      class="com.some.Class">
      <property name="property" value="#{base.module.elementToSearch}" />
</bean>

Et ma classe.java

file: Class.java
public void setProperty(final List<Integer> elements){
    this.elements = elements;
}

Mais lors du débogage, les éléments de paramètre n'obtiennent que le dernier élément de la liste, donc, il y a une liste d'un élément avec la valeur "6", au lieu d'une liste avec 6 éléments.

J'ai essayé d'autres approches, comme l'ajout de valeur uniquement, #{base.module}mais il ne trouve aucun paramètre dans le fichier de propriétés.

Une solution de contournement consiste à avoir dans le fichier elements.properties une liste séparée par des virgules, comme:

base.module.elementToSearch=1,2,3,4,5,6

et utilisez-le comme une chaîne et analysez-le, mais y a-t-il une meilleure solution?

RamonBoza
la source
donc je dois le passer comme une chaîne séparée par des virgules et analyser dans la méthode.
RamonBoza
Exactement, même si certaines bibliothèques font déjà cela pour vous (apache commons) - commons.apache.org/configuration/howto_properties.html
Colin Hebert
Voici une réponse qui vous donne au moins un résultat Set <String>. Pas tout à fait une List <String>, mais probablement suffisante dans de nombreux cas! stackoverflow.com/questions/5274362/…
John Rix

Réponses:

189

Si vous définissez votre tableau dans un fichier de propriétés comme:

base.module.elementToSearch=1,2,3,4,5,6

Vous pouvez charger un tel tableau dans votre classe Java comme ceci:

  @Value("${base.module.elementToSearch}")
  private String[] elementToSearch;
svlada
la source
5
Mes éléments contiennent une virgule. Comment échapper au séparateur? '\,' même '\\,' ne fonctionnent pas.
banterCZ
Vous pouvez essayer de les obtenir sous forme de liste d'entiers, puis les convertir @Value ("$ {base.module.elementToSearch}") private List <Integer> elementToSearch;
Gal Bracha
+1, exactement ce dont j'avais besoin. Malheureusement, lire les valeurs séparées par des virgules dans un List<String>de la même manière ne semble pas fonctionner (la liste n'aura qu'un seul élément).
Jonik
4
Je peux confirmer que l'utilisation en String[]tant que type fonctionne, alors que l'utilisation List<String>ne fonctionne pas.
Wim Deblauwe
2
Si vous souhaitez que cela fonctionne avec List<String>au lieu de String[], vous devez ajouter au moins un <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">à votre fichier applicationContext.xml. Sinon, le service de conversion n'est pas utilisé, mais les éditeurs de propriétés par défaut, qui ne prennent pas en charge la conversion de chaînes en collections, uniquement des tableaux: docs.spring.io/spring/docs/current/spring-framework-reference
Clemens Klein-Robbenhaar
36

Et si vous utilisez un séparateur différent autre que la virgule, vous pouvez également l'utiliser.

@Value("#{'${my.config.values}'.split(',')}")
private String[] myValues;   // could also be a List<String>

et

dans les propriétés de votre application, vous pourriez avoir

my.config.values=value1, value2, value3
RK Punjal
la source
cet usage fonctionne également avec d'autres annotations, j'ai utilisé comme @KafkaListener {topics = "# {'$ {ArrayProperty}'. split (',')}"} pour l'auditeur de kafka de printemps
AsyncTask
32

Voici un exemple de la façon dont vous pouvez le faire dans Spring 4.0+

application.properties contenu:

some.key=yes,no,cancel

Code Java:

@Autowire
private Environment env;

...

String[] springRocks = env.getProperty("some.key", String[].class);
Juha Hanka
la source
c'est ce que je veux, mais dans env vars ... je devrais pouvoir utiliser SOME_KEY_0_ = yes SOME_KEY_1 = no, etc. dans env vars, mais mon getProperty revient nul
Rhubarb
0

Avec un Spring Boot, on peut faire ce qui suit:

application.properties

values[0]=abc
values[1]=def

Classe de configuration

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
@ConfigurationProperties
public class Configuration {

    List<String> values = new ArrayList<>();

    public List<String> getValues() {
        return values;
    }

}

Ceci est nécessaire, sans cette classe ou sans le values classe, cela ne fonctionne pas.

Classe d'application Spring Boot

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.List;

@SpringBootApplication
public class SpringBootConsoleApplication implements CommandLineRunner {

    private static Logger LOG = LoggerFactory.getLogger(SpringBootConsoleApplication.class);

    // notice #{} is used instead of ${}
    @Value("#{configuration.values}")
    List<String> values;

    public static void main(String[] args) {
        SpringApplication.run(SpringBootConsoleApplication.class, args);
    }

    @Override
    public void run(String... args) {
        LOG.info("values: {}", values);
    }

}
Betlista
la source
0

Si vous devez passer le symbole astérisque, vous devez l'envelopper de guillemets.

Dans mon cas, je dois configurer des cors pour les websockets. J'ai donc décidé de mettre les urls cors dans application.yml. Pour prod env, j'utiliserai des URL spécifiques, mais pour les développeurs, il est possible d'utiliser uniquement *.

Dans le fichier yml, j'ai:

websocket:
  cors: "*"

Dans la classe Config, j'ai:

@Value("${websocket.cors}")
private String[] cors;
Ruslan Sheremet
la source