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

时间:2015-02-05 23:15:55

标签: jackson

我有一个这样的课程:

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

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

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

我有一个包含此str的字符串{ "address" : "something" }。请注意,没有"名称"在json的领域。如果我做这样的事情:

mapper.readValue(str, Person.class);

然后我实际上得到一个名字设置为null的Person对象。有没有办法配置映射器来抛出异常,或者返回空引用而不是Person?我希望杰克逊能够将失踪字段视为失败,并且不希望对生成的对象字段进行明确的空检查。

3 个答案:

答案 0 :(得分:25)

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

/* 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;
    }
}

答案 1 :(得分:3)

不幸的是,杰克逊目前不支持此事。

解决方案可能是在构造函数中添加验证。理想情况下,如果您不希望将这些值序列化为null,则表示您根本不应将它们作为null(以其他方式构造)。例如,

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

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

虽然它们在required注释中具有@JsonProperty属性,但在反序列化期间根本不支持它,并且仅用于装饰JSON模式。见topic

答案 2 :(得分:0)

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

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);
        }
    });
}