当提供 json 与目标 class 类型不同 class 时,Jackson 不会在反序列化时抛出异常
Jackson not throwing an exception on deserializing when provided json is different class type than targeted class
我有两个 classes A
和 B
,它们都有 public 吸气剂和构造函数,上面标有 @JsonCreator
和 @JsonProperty
构造函数参数。当提供正确的 json 时,这两个 classes 都被正确反序列化。但是,当我提供 json 是 class 类型 A 的投影并尝试将其反序列化为 B 类型对象时,我希望抛出异常。结果发现jackson将json正确反序列化为B类型对象,但是这个对象只是null。这是默认行为吗?我的 ObjectMapper
是用 new ObjectMapper()
创建的。我能否以任何方式配置它,使其在所述情况下抛出异常?
Class一个实现:
@JsonIgnoreProperties(ignoreUnknown = true)
final class A {
private final String propertyA;
@JsonCreator
A(@JsonProperty("propertyA") String propertyA) {
this.propertyA = propertyA;
}
public String getPropertyA() {
return propertyA;
}
@Override
public String toString() {
return "A{" +
"propertyA='" + propertyA + '\'' +
'}';
}
}
ClassB实现:
@JsonIgnoreProperties(ignoreUnknown = true)
final class B {
private final String propertyB;
@JsonCreator
B(@JsonProperty("propertyB") String propertyB) {
this.propertyB = propertyB;
}
public String getPropertyB() {
return propertyB;
}
@Override
public String toString() {
return "B{" +
"propertyB='" + propertyB + '\'' +
'}';
}
}
Json 与 class B 投影:{"propertyB":"propertyBValue"}
反序列化代码:
String jsonWithBObject = "{\"propertyB\":\"propertyBValue\"}";
A deserializedAObject = mapFromJsonToObject(jsonWithBObject, A.class);
private <T> T mapFromJsonToObject(String json, Class<T> targetClass) {
try {
return objectMapper.readValue(json, targetClass);
} catch (JsonProcessingException exception) {
throw new RuntimeException();
}
}
而在运行这段代码之后,没有抛出异常,并且deserializdAObject
包含:A{propertyA='null'}
@JsonIgnoreProperties(ignoreUnknown = true)
导致 jackson 忽略未知属性,反序列化后得到的对象是所有属性都使用默认值初始化的对象(对于非基元是 null
)。
使用 required=true
强制 Jackson 在缺少 属性 的情况下抛出异常。
@JsonCreator
B(@JsonProperty(value="propertyB", required=true) String propertyB) {
this.propertyB = propertyB;
}
使用 @JsonProperty(required = true)
强制 Jackson 在缺少密钥时抛出异常
仅部分支持此 属性。摘自 Jackson javadoc:
Note that as of 2.6, this property is only used for Creator
Properties, to ensure existence of property value in JSON:
for other properties (ones injected using a setter or mutable
field), no validation is performed. Support for those cases
may be added in future.
我有两个 classes A
和 B
,它们都有 public 吸气剂和构造函数,上面标有 @JsonCreator
和 @JsonProperty
构造函数参数。当提供正确的 json 时,这两个 classes 都被正确反序列化。但是,当我提供 json 是 class 类型 A 的投影并尝试将其反序列化为 B 类型对象时,我希望抛出异常。结果发现jackson将json正确反序列化为B类型对象,但是这个对象只是null。这是默认行为吗?我的 ObjectMapper
是用 new ObjectMapper()
创建的。我能否以任何方式配置它,使其在所述情况下抛出异常?
Class一个实现:
@JsonIgnoreProperties(ignoreUnknown = true)
final class A {
private final String propertyA;
@JsonCreator
A(@JsonProperty("propertyA") String propertyA) {
this.propertyA = propertyA;
}
public String getPropertyA() {
return propertyA;
}
@Override
public String toString() {
return "A{" +
"propertyA='" + propertyA + '\'' +
'}';
}
}
ClassB实现:
@JsonIgnoreProperties(ignoreUnknown = true)
final class B {
private final String propertyB;
@JsonCreator
B(@JsonProperty("propertyB") String propertyB) {
this.propertyB = propertyB;
}
public String getPropertyB() {
return propertyB;
}
@Override
public String toString() {
return "B{" +
"propertyB='" + propertyB + '\'' +
'}';
}
}
Json 与 class B 投影:{"propertyB":"propertyBValue"}
反序列化代码:
String jsonWithBObject = "{\"propertyB\":\"propertyBValue\"}";
A deserializedAObject = mapFromJsonToObject(jsonWithBObject, A.class);
private <T> T mapFromJsonToObject(String json, Class<T> targetClass) {
try {
return objectMapper.readValue(json, targetClass);
} catch (JsonProcessingException exception) {
throw new RuntimeException();
}
}
而在运行这段代码之后,没有抛出异常,并且deserializdAObject
包含:A{propertyA='null'}
@JsonIgnoreProperties(ignoreUnknown = true)
导致 jackson 忽略未知属性,反序列化后得到的对象是所有属性都使用默认值初始化的对象(对于非基元是 null
)。
使用 required=true
强制 Jackson 在缺少 属性 的情况下抛出异常。
@JsonCreator
B(@JsonProperty(value="propertyB", required=true) String propertyB) {
this.propertyB = propertyB;
}
使用 @JsonProperty(required = true)
强制 Jackson 在缺少密钥时抛出异常
仅部分支持此 属性。摘自 Jackson javadoc:
Note that as of 2.6, this property is only used for Creator Properties, to ensure existence of property value in JSON: for other properties (ones injected using a setter or mutable field), no validation is performed. Support for those cases may be added in future.