I am having trouble writing out a java object to a yml file using SnakeYaml. I have setup a spring boot project with a simple application.yml that I convert to a set of java objects. In the real application some objects get added and when the application is done I want to write out the new application.yml.
The input application.yml looks like this:
sample:
name: toyota
cars:
- model: prius
colour: silver
- model: avensis
colour: red
The java object that maps this application.yml:
@Configuration
@ConfigurationProperties(prefix="sample")
public class Config {
private String name;
private final List<Car> cars = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Car> getCars() {
return cars;
}
}
And the sample class that writes out the yaml:
@Component
public class Example {
@Autowired
private Config config;
@PostConstruct
private void init(){
Yaml yaml = new Yaml();
StringWriter writer = new StringWriter();
yaml.dump(config, writer);
System.out.println(writer.toString());
}
}
The output is just: name: toyota
(ommitted some yaml settings that also get writen out). However I want the output to be exactly the same as the input:
sample:
name: toyota
cars:
- model: prius
colour: silver
- model: avensis
colour: red
Is there a way to do this?
User flyx correctly pointed out the following documentation.
My adjusted code:
Constructor constructor = new Constructor(Config.class);
TypeDescription configDescription = new TypeDescription(Config.class);
configDescription.putListPropertyType("cars", Car.class);
constructor.addTypeDescription(configDescription);
Yaml yaml = new Yaml(constructor);
StringWriter writer = new StringWriter();
yaml.dump(config, writer);
System.out.println(writer.toString());
Gives the following output:
$$beanFactory: !!org.springframework.beans.factory.support.DefaultListableBeanFactory
allowBeanDefinitionOverriding: true
allowEagerClassLoading: true
autowireCandidateResolver: !!org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver {}
beanClassLoader: !!sun.misc.Launcher$AppClassLoader {}
beanExpressionResolver: !!org.springframework.context.expression.StandardBeanExpressionResolver {}
cacheBeanMetadata: true
conversionService: null
dependencyComparator: !!org.springframework.core.annotation.AnnotationAwareOrderComparator {}
parentBeanFactory: null
serializationId: application
tempClassLoader: null
typeConverter: !!org.springframework.beans.SimpleTypeConverter {conversionService: null}
name: toyota
Without an explicit setter on the list of Car, the list will not be printed.
After changing:
private final List<Car> cars = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Car> getCars() {
return cars;
}
To this:
private List<Car> cars = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public List<Car> getCars() {
return cars;
}
The code works.