paoloaq
paoloaq

Reputation: 317

Spring - YML array property is null

I am vainly trying to read an array of strings from the application.yml. Both the Environment and the @Value annotation, always return null.

Everything works if I read an item, instead of the entire array.

Here the code:

Sources


Boot Application and Rest Controllers

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
class WithEnvCtrl {

    @Autowired
    private Environment env;

    @RequestMapping(value = "/with_env", method = { RequestMethod.GET, RequestMethod.POST }, produces = "application/json")
    public String test() {

        System.err.println(env.getProperty("this.is.array[0]"));
        System.err.println(env.getProperty("this.is.array", List.class));
        System.err.println(env.getProperty("this.is.array", String[].class));

        return env.getProperty("this.is.array[0]");
    }
}

@RestController
class WithValueAnnotation {

    @Value("${this.is.array[0]}")
    private String first;

    @Value("${this.is.array}")
    private List<String> list;

    @Value("${this.is.array}")
    private String[] array;

    @RequestMapping(value = "/with_value_annotation", method = { RequestMethod.GET, RequestMethod.POST }, produces = "application/json")
    public String test() {

        System.err.println(first);
        System.err.println(list);
        System.err.println(array);

        return first;
    }
}

application.yml file

this:
  is:
    array: 
      - "casa"
      - "pesenna"

Results


The WithEnvCtrl.test method prints:

casa
null
null
null

The WithValueAnnotation.test method correctly sets the variable first with the first element of the array (casa). However, the annotations @Value on the attributes list and array cause the exception:

java.lang.IllegalArgumentException: Could not resolve placeholder 'this.is.array' in string value "${this.is.array}"

Here is an example project: property-array.

Many thanks in advance!

Upvotes: 3

Views: 5632

Answers (1)

paoloaq
paoloaq

Reputation: 317

Solved by:

  • using the annotation @ConfigurationProperties;
  • declaring an attribute with the same name as the yml property;
  • defining the get method for the attribute;
  • initializing the attribute or defining the set method.

Here the code:

import java.util.List;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
@ConfigurationProperties(prefix="this.is")
class WithValueAnnotation {

    private List<String> array;

    public List<String> getArray(){
        return this.array;
    }

    public void setArray(List<String> array){
        this.array = array;
    }

    @RequestMapping(value = "/test_cfg", method = { RequestMethod.GET,
            RequestMethod.POST }, produces = "application/json")
    public String test() {

        System.err.println(array);

        return array.toString();
    }
}

Thanks @Quagaar.

Upvotes: 3

Related Questions