Archivo Spring .properties: obtener el elemento como una matriz

94

Estoy cargando atributos de propiedades desde un .propertiesarchivo usando Spring de la siguiente manera:

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

El archivo xml de primavera

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

Y mi Class.java

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

Pero al depurar, los elementos del parámetro solo incluyen el último elemento en la lista, por lo que hay una lista de un elemento con valor "6", en lugar de una lista con 6 elementos.

Probé otros enfoques, como agregar valor solo, #{base.module}pero luego no encuentra ningún parámetro en el archivo de propiedades.

Una solución alternativa es tener en el archivo elements.properties una lista separada por comas, como:

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

y utilícelo como una cadena y analícelo, pero ¿hay una solución mejor?

RamonBoza
fuente
así que necesito pasarlo como una cadena separada por comas y analizar el método.
RamonBoza
Exactamente, aunque hay algunas bibliotecas que ya lo están haciendo por usted (apache commons) - commons.apache.org/configuration/howto_properties.html
Colin Hebert
Aquí hay una respuesta que al menos le da un resultado Set <String>. No es una List <String>, ¡pero probablemente suficiente en muchos casos! stackoverflow.com/questions/5274362/…
John Rix

Respuestas:

194

Si define su matriz en el archivo de propiedades como:

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

Puede cargar dicha matriz en su clase Java de esta manera:

  @Value("${base.module.elementToSearch}")
  private String[] elementToSearch;
svlada
fuente
5
Mis elementos contienen coma. ¿Cómo escapo del separador? '\,' incluso '\\,' no funcionan.
banterCZ
Puede intentar obtenerlos como una lista de enteros y luego convertirlos @Value ("$ {base.module.elementToSearch}") private List <Integer> elementToSearch;
Gal Bracha
+1, justo lo que necesitaba. Desafortunadamente, leer valores separados por comas en a List<String>de la misma manera no parece funcionar (la lista tendrá un solo elemento).
Jonik
5
Puedo confirmar que el uso String[]como tipo funciona, donde el uso List<String>no funciona.
Wim Deblauwe
3
Si desea que esto funcione en List<String>lugar de String[], debe agregar al menos un <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">a su applicationContext.xml. De lo contrario, no se usa el servicio de conversión, sino los editores de propiedades predeterminados, que no admiten la conversión de cadenas en colecciones, solo matrices: docs.spring.io/spring/docs/current/spring-framework-reference/…
Clemens Klein-Robbenhaar
37

Y en caso de que tenga un delimitador diferente a la coma, también puede usarlo.

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

y

en las propiedades de su aplicación podría tener

my.config.values=value1, value2, value3
RK Punjal
fuente
este uso también funciona con otras anotaciones, utilicé como @KafkaListener {topics = "# {'$ {ArrayProperty}'. split (',')}"} para el oyente de
Spring Kafka
32

Aquí hay un ejemplo de cómo puede hacerlo en Spring 4.0+

application.properties contenido:

some.key=yes,no,cancel

Código Java:

@Autowire
private Environment env;

...

String[] springRocks = env.getProperty("some.key", String[].class);
Juha Hanka
fuente
esto es lo que quiero, pero en env vars ... Debería poder usar SOME_KEY_0_ = yes SOME_KEY_1 = no, etc.en env vars, pero mi getProperty regresa nulo
Rhubarb
1

Con un Spring Boot se puede hacer lo siguiente:

application.properties

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

Clase de configuración

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

}

Esto es necesario, sin esta clase o sin la valuesclase en, no está funcionando.

Clase de aplicación 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
fuente
0

Si necesita pasar el símbolo de asterisco, debe envolverlo entre comillas.

En mi caso, necesito configurar cors para websockets. Entonces, decidí poner las URL de cors en application.yml. Para prod env usaré URL específicas, pero para dev está bien usar solo *.

En el archivo yml tengo:

websocket:
  cors: "*"

En la clase de configuración tengo:

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