YAML file : mapping values to Object list with Spring Boot 7

I struggled a bit with a thing that could be so simple. I had a set of rules that I wanted to map as an Object list and documentations was not very clear. So I’ve decided to put my 2 cents, and detail the steps to make it works properly.

To be able to do this, you have to have a Spring Boot project, with SnakeYAML (in much Spring Boot starter projects, the dependancy is already in).

Let’s go

I have a set of rules, that is corresponding to a POJO in my Java project, here is the YAML representation :

configuration.yml

rules: 
     networkRules:
           -
               size: 10
               prefix: '255'
               regex:  '^([ ... some regex])\S$'
            -
               size: 11
               prefix: '180'
               regex: '^([ ... a cool regex ...])\S$'
            -
               size: 10
               prefix: '128'
               regex:  '^([ ... another regex...])\S$'

Your yml file being formatted like this, let’s browse a bit the Java code :

Let’s begin with our object model (the POJO) :

NetworkRule.java

@Data
@NoArgsConstructor
public class NetworkRule {
    
    private int size;
    private String prefix;
    private String regex;

    public NetworkRule(int size, String prefix, String regex) {
        this.size = size;
        this.prefix = prefix;
        this.regex = regex;
    }

    // GETTERS & SETTERS
}

You can create your getters and setters for each of your attributes, I didn’t here because I’m using lombok plugin which let us annotate my class with @Data and generate the whole bunch of getters, setters, toString, hash … methods.

ConfigurationService.java

@Service
@ConfigurationProperties(prefix = "rules")
public class ConfigurationService {
    private List<NetworkRule> networkRules = new ArrayList<>();

    @PostConstruct
    public void init() {
        for(NetworkRule current : this.getNetworkRules()) {
             // DO STUFF, or you can call your get method wherever you want
        }
    }

    public List<NetworkRule> getNetworkRules() {
        return this.networkRules;
    }
}

 Conclusion

I have been fighting with this as I though like @Value(« ${foo} ») , the @ConfigurationProperties would init the object during the construction of my object. But it was not the case, you have to call your getter method on your object list in order to retrieve it.

The most helpful stackoverflow post was this one (I also added an answer :p) : http://stackoverflow.com/questions/32593014/mapping-list-in-yaml-to-list-of-objects-in-spring-boot/34879008#34879008

7 thoughts on “YAML file : mapping values to Object list with Spring Boot

  1. Répondre daniel regala mai 23, 2016 13 h 00 min

    Do you have a sample git repository for this?

  2. Répondre David juil 12, 2016 15 h 19 min

    Merci ! Exactement ce que je cherchais !!

  3. Répondre GarciaPL août 3, 2016 21 h 24 min

    I had two problems with that example. First of all configuration.yml file need some refactoring, I mean that every dash should be in the same line with keyword ‘size’, not in separate line. Second it was that constructor from NetworkRule should be removed, because of it makes that Spring is confused.

  4. Répondre Harie mar 8, 2017 11 h 15 min

    it did not work in my case. i have some thing like this:
    commands:
    details:

    id: « PauseQ »
    type: « bean »
    beanClass: «  »
    beanId: «  »
    operationName: « pauseAllQ »
    staticCall: « 0 »
    commandText: «  »
    – more commands follows

    @ConfigurationProperties(« commands.details »)
    public class CommandProperties {
    private String id;
    private String type;
    private String beanClass;
    private String beanId;
    private String staticCall;
    private String operationName;
    private String commandText;
    //constructor with arguments
    //getters setters
    }

    @Service
    @ConfigurationProperties(prefix = « commands »)
    public class CommandsConfigurationService {
    private List commands = new ArrayList();
    @PostConstruct
    public void init() {
    System.out.println(« current.getOperationName() »);

    for(CommandProperties current : this.getCommands()) {
    System.out.println(current.getOperationName());
    }
    }
    public List getCommands() {
    return commands;
    }
    // public void setCommands(List commands) {
    // this.commands = commands;
    // }

    }

    on Spring controller i invoke
    commandsConfigService.getCommands(); and 0 commands found

Laisser un commentaire