Handling Missing Fields with SnakeYaml
Suppose I have a simple class with two fields, getters and setters. I want to sometimes serialize and deserialize objects of this class.
public class Foo {
private String a;
private int b;
public void setA(String a) {
System.out.println("a setter called");
this.a = Objects.requireNonNull(a, "Required non null field.");
}
public void setB(int b) {
System.out.println("b setter called");
this.b = b;
}
public String getA() {
return a;
}
public int getB() {
return b;
}
public static void main(String[] args) {
Representer representer = new Representer();
representer.getPropertyUtils().setSkipMissingProperties(false);
Yaml yaml = new Yaml(new Constructor(), representer);
String doc = "b: 10";
Foo testBean = yaml.loadAs(doc, Foo.class);
}
}
I want the code in the main method to throw an exception because the doc
field is missing a
. Unfortunately, this doesn't work by default.
Can I configure SnakeYaml for this?
source to share
Using the builder pattern is probably the best approach. Putting it all together made it easier for him to do it with Jackson (not sure if he / doesn't handle SnakeYaml on its own) and Immutables ( https://immutables.github.io/ ) for the builder.
Note that you can write the creator yourself and you can do the validation in the build()
builder method , but Immutables makes it all a little easier.
First, your model class:
@Value.Immutable
@JsonDeserialize(builder = ImmutableFoo.Builder.class)
public interface Foo {
String getA();
int getB();
}
Note that getA()
it cannot return null by default (you could annotate it with, @Nullable
or do it Optional<String>
if you want to change this behavior). After starting the annotation processor, you will have a class ImmutableFoo
with a constructor with the desired semantics.
Then switch your de-serialization to use Jackson (which SnakeYaml apparently uses under the hood, so it shouldn't be super different):
new ObjectMapper(new YAMLFactory()).readValue("b: 10", Foo.class);
Now a value will be selected JsonMappingException
whose reason is in the builder:
java.lang.IllegalStateException: Unable to create Foo, some required attributes are not set [a]
If you want to avoid Immutables, you can do such a check in your own developer.
source to share