Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring @Value with arraylist split and default empty list

I am struggling in obtaining both of the behaviors requested in the title. 1) I have a property file like this:

my.list=a,b,c

2) If that property is not present I want an empty list

Why the following is throwing me syntax error?

@Value("#{'${my.list}'.split(',') : T(java.util.Collections).emptyList()}")
like image 234
Phate Avatar asked Mar 19 '18 15:03

Phate


People also ask

How to use @value with defaults in spring?

Using Spring @Value with Defaults 1 Overview. Spring's @Value annotation provides a convenient way to inject property values into components. ... 2 String Defaults. If some.key cannot be resolved, then stringWithDefaultValue will be set to the default value of “ my default value”. 3 Primitives. ... 4 Arrays. ... 5 Using SpEL. ... 6 Conclusion. ...

How to split a string into an ArrayList in Java?

Java: How to split a String into an ArrayList. Here are a few ways to split (or convert, or parse) a string of comma separated values: input = "aaa,bbb,ccc"; String[] arr = input.split(","); List<String> l = Arrays.asList(input.split(",")); List<String> l2 = new ArrayList<>(Arrays.asList(input.split(",")));

How do I inject a list in spring?

Our List contains a single element, which is equal to the value we set in our properties file. In order to properly inject a List, we need to use a special syntax called Spring Expression Language (SpEL):

How does spring handle comma-separated values in arrays?

Let's see how Spring behaves when we set our variable type to String []: We can see that Spring correctly assumes our delimiter is a comma and initializes the array accordingly. We should also note that, by default, injecting an array works correctly only when we have comma-separated values.


3 Answers

There is a way to get it working:

@Value("#{T(java.util.Arrays).asList('${my.list:}')}") 
private List<String> list;

After the colon at my.list: you can set the default value. For now its emtpy.

like image 81
Patrick Avatar answered Oct 08 '22 17:10

Patrick


Did came across similar requirement. Below is one of the possible way of doing this :

@Value("#{'${some.key:}'.split(',')}")
Set<String> someKeySet;

I think similar should apply for List as well.
Pay attention to ":" after property name. It defaults to blank string which in turn would give empty list or set.

like image 23
bittu Avatar answered Oct 08 '22 17:10

bittu


I don't think you can use nested SPEL. one way to achieve this is

@Value("${server.name:#{null}}")
private String someString;

private List<String> someList;

@PostConstruct
public void setList() {
  someList = someString == null ? Collections.emptyList() : Arrays.asList(someString.split(","));
}
like image 3
pvpkiran Avatar answered Oct 08 '22 19:10

pvpkiran