115

I'm loading properties attributes from a .properties file using Spring as follows:

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

The spring xml file

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

And my Class.java

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

But when debugging, the parameter elements only get the last element into the list, so, there is a list of one element with value "6", instead of a list with 6 elements.

I tried other approaches, like adding in value only #{base.module} but then it finds no parameter in the properties file.

A workaround is to have in elements.properties file a list separated by commas, like:

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

and use it as a String and parse it, but is there a better solution?

Michael Currie
  • 13,721
  • 9
  • 42
  • 58
RamonBoza
  • 8,898
  • 6
  • 36
  • 48
  • possible duplicate of [How do I specify values in a properties file so they can be retrieved using ResourceBundle#getStringArray?](http://stackoverflow.com/questions/226050/how-do-i-specify-values-in-a-properties-file-so-they-can-be-retrieved-using-resou) – Colin Hebert Jun 02 '11 at 09:53
  • so I need to pass it as a comma separated string and parse in method. – RamonBoza Jun 02 '11 at 10:00
  • Exactly, although there is some libs already doing that for you (apache commons) - http://commons.apache.org/configuration/howto_properties.html – Colin Hebert Jun 02 '11 at 10:01
  • Here's an answer that at least gives you a Set result. Not quite a List, but probably sufficient in many cases! http://stackoverflow.com/questions/5274362/reading-a-dynamic-property-list-into-a-spring-managed-bean – John Rix Apr 09 '15 at 13:52
  • @Value("${key:one,two,three}") String[] arrayWithDefaults; – Kanagavelu Sugumar Jun 30 '21 at 10:21

5 Answers5

224

If you define your array in properties file like:

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

You can load such array in your Java class like this:

  @Value("${base.module.elementToSearch}")
  private String[] elementToSearch;
Jonik
  • 80,077
  • 70
  • 264
  • 372
svlada
  • 3,218
  • 2
  • 25
  • 36
  • 6
    My elements contain comma. How do I escape separator? '\,' even '\\,' do not work. – banterCZ Mar 20 '12 at 10:28
  • You can try to get them as list of integer and then converts them @Value( "${base.module.elementToSearch}") private List elementToSearch; – Gal Bracha Mar 21 '12 at 16:17
  • +1, just what I needed. Unfortunately reading comma-separated values into a `List` in the same fashion doesn't seem to work (the list will have just one element). – Jonik May 29 '13 at 08:36
  • I am failing to read them in to an array (String[]). Is this supposed to work? – David Karlsson Oct 25 '13 at 13:31
  • 5
    I can confirm that using `String[]` as type works, where using `List` does not work. – Wim Deblauwe Apr 29 '14 at 14:38
  • Under the hood this uses `org.springframework.util.StringUtils.commaDelimitedListToStringArray(String)` to split the string, and this util method does not support any escapes, so if your values contain commas, you are out of luck and need to write your own converter. – Clemens Klein-Robbenhaar Apr 30 '15 at 12:52
  • 3
    If you want this to work with `List` instead of `String[]`, you need to add at least a `` to your `applicationContext.xml`. Otherwise the conversion service is not used but the default property editors, which do not support converting Strings to collections, only arrays: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#core-convert-Spring-config – Clemens Klein-Robbenhaar Apr 30 '15 at 14:01
47

And incase you a different delimiter other than comma, you can use that as well.

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

and

in your application properties you could have

my.config.values=value1, value2, value3
R K Punjal
  • 1,445
  • 1
  • 15
  • 20
  • 1
    this usage also works with other annotations, I used like @KafkaListener{topics= "#{'${ArrayProperty}'.split(',')}"} for spring kafka listener – AsyncTask Sep 06 '18 at 16:19
35

Here is an example of how you can do it in Spring 4.0+

application.properties content:

some.key=yes,no,cancel

Java Code:

@Autowire
private Environment env;

...

String[] springRocks = env.getProperty("some.key", String[].class);
Moshe Katz
  • 15,992
  • 7
  • 69
  • 116
Juha Hanka
  • 639
  • 6
  • 5
  • this is what I want, but in env vars... I should be able to use SOME_KEY_0_=yes SOME_KEY_1=no, etc in env vars, but my getProperty is coming back null – Rhubarb Apr 30 '20 at 20:56
12

With a Spring Boot one can do the following:

application.properties

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

Configuration class

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

}

This is needed, without this class or without the values in class it is not working.

Spring Boot Application class

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
  • 10,327
  • 13
  • 69
  • 110
-2

If you need to pass the asterisk symbol, you have to wrap it with quotes.

In my case, I need to configure cors for websockets. So, I decided to put cors urls into application.yml. For prod env I'll use specific urls, but for dev it's ok to use just *.

In yml file I have:

websocket:
  cors: "*"

In Config class I have:

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