将 Jackson 配置为在缺少字段时抛出异常

Configure Jackson to throw an exception when a field is missing

我有一个 class 这样的:

public class Person {
  private String name;
  public String getName(){
    return name;
  }
}

我正在使用这样配置的 ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

我有一个包含此 { "address" : "something" } 的字符串 str。请注意,json 中没有 "name" 字段。如果我这样做:

mapper.readValue(str, Person.class);

然后我实际上取回了一个名称设置为 null 的 Person 对象。有没有办法将映射器配置为抛出异常,或者 return 空引用而不是 Person?我希望 Jackson 将缺少的字段视为失败,并且不想对结果对象的字段进行显式空检查。

很遗憾,Jackson 目前不支持此功能。

解决方案可能是在您的构造函数中添加验证。理想情况下,如果您不想将这些值序列化为 null's,这确实意味着您根本不应该将它们作为 null's(以其他方式构造)。例如,

public class Person {
  private String name;
  public Person() {
     checkNotNull(name);
  }
} 

然而,这可能并不适用于所有情况,特别是如果您使用的对象不是通过 serializing/deserializing。

虽然它们在 @JsonProperty 注释中有 required 属性,但在反序列化过程中根本不支持它,并且仅在装饰 JSON 模式时引入。看到这个 topic

从 Jackson 2.6 开始,有 is a way,但它不适用于 class 属性注释,仅 构造函数注释 :

/* DOES *NOT* THROW IF bar MISSING */
public class Foo {    
    @JsonProperty(value = "bar", required = true)
    public int bar;
}

/* DOES THROW IF bar MISSING */
public class Foo {
    public int bar;
    @JsonCreator
    public Foo(@JsonProperty(value = "bar", required = true) int bar) {
        this.bar = bar;
    }
}

我有一个类似的问题,反序列化后我想知道是否一切都很好。 此方法使用 JsonProperty Annotation 遍历所有字段,检查它是否不为 null 并在递归列表中查看是否 class 更深入(以避免无限循环)。

private void checkIfFieldsAreNotNull(Object o, List<Class> recursive) {
    Arrays.asList(o.getClass().getDeclaredFields()).stream().filter(field -> field.isAnnotationPresent(JsonProperty.class)).forEach(field -> {
        field.setAccessible(true);
        try {
            assertNotNull(field.get(o));
            if(recursive.contains(field.getType())) {
                checkIfFieldsAreNotNull(field.get(o), recursive);
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    });
}