假设我有一个简单的类,它包含两个字段:getter 和 setter。我有时想序列化和反序列化这个类的对象。
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);
}
}
我希望 main 方法中的代码抛出一些异常,因为 doc
中缺少字段 a
。不幸的是,它在默认情况下不起作用。
我能以某种方式配置 SnakeYaml 吗?
最佳答案
使用构建器模式可能是最好的方法。将所有这些放在一起,最终使用 Jackson 更容易做到这一点(不确定 SnakeYaml 本身是否可行)和构建器的 Immutables ( https://immutables.github.io/ )。
请注意,您可以自己编写构建器,并且可以在 build()
中进行验证构建器的方法,但 Immutables 使这一切变得更容易一些。
首先,你的模型类:
@Value.Immutable
@JsonDeserialize(builder = ImmutableFoo.Builder.class)
public interface Foo {
String getA();
int getB();
}
请注意,默认情况下 getA()
不能返回 null(如果您想更改该行为,可以使用 @Nullable
对其进行注释或将其设为 Optional<String>
)。运行注释处理器后,您将得到一个 ImmutableFoo
。使用具有所需语义的构建器进行分类。
然后将你的反序列化切换为使用 Jackson(它显然在底层使用了 SnakeYaml,所以应该不会有太大的不同):
new ObjectMapper(new YAMLFactory()).readValue("b: 10", Foo.class);
这将抛出一个 JsonMappingException
其原因在于构建器:
java.lang.IllegalStateException: Cannot build Foo, some of required attributes are not set [a]
如果你想避免不可变,你可以在你自己的构建器中进行这种验证。
关于java - 使用 SnakeYaml 处理缺失字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43735911/