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
Do you have a sample git repository for this?
Nope, I only have the explanations & code example here. Do you have any problem trying to do this ?
Merci ! Exactement ce que je cherchais !!
😀
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.
I’m wondering what is your Spring version … I’m using Spring Boot 1.3 and my class needed a constructor in order to map the values. It couldn’t be done automatically…
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
Good!
Pingback: Is there a way to mapping values to Object list from YAML - JavaTechji