将 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);
}
});
}
我有一个 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);
}
});
}