java/jackson - @JsonValue/@JsonCreator 和 null
java/jackson - @JsonValue/@JsonCreator and null
我有一个 Value
class 包含一个值:
public class Value {
protected final Object value;
@JsonValue
public Object getValue() {
return value;
}
@JsonCreator
public Value(final Object value) {
this.value = value;
}
}
此 Value
class 作为字段(在其他字段中)嵌入到数据 class:
class Data {
protected final Value value;
@JsonProperty("value")
public Value getValue() {
return value;
}
...
@JsonCreator
public Data(@JsonProperty("value") final Value value, ...) {
this.value = value;
....
}
}
当输入 JSON 对 data
对象的 value
字段有 null
时(参见下面的示例),Data.value
为空。我想将 Data.value
设置为 new Value(null)
。也就是说,数据对象必须持有一个非空值对象,它持有的是null。
{
"value" : null,
...
}
实现此目的最简单的方法是什么?我当然可以更改 Data
的构造函数,但我想知道 Jackson 是否可以自动解决这个问题。
您可以编写自定义反序列化程序并根据您的要求覆盖 getNullValue()
方法,例如
public final class InstantiateOnNullDeserializer
extends JsonNodeDeserializer
{
@Override
public JsonNode getNullValue()
{
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.convertValue(new Value(null), JsonNode.class);
return node;
}
}
并将其注册到您的 Data class
的值字段
class Data {
@JsonDeserialize(using = InstantiateOnNullDeserializer.class)
protected final Value value;
@JsonProperty("value")
public Value getValue() {
return value;
}
@JsonCreator
public Data(Value value) {
this.value = value;
}
}
请注意,您需要删除 @JsonProperty("value")
以避免参数类型不匹配。通过删除 JsonProperty 注释,您创建了一个所谓的 "delegate creator",
Jackson 将首先将 JSON 绑定到参数的类型中,然后调用创建者
我认为如果不创建自己的反序列化器或修改构造函数(或 @JsonCreator
),这是不可能的。
来自a good old thread in the Jackson User Group:
@JsonProperty
does not support transformations, since the data binding is based on incremental parsing and does not have access to full tree representation.
因此,为了避免自定义反序列化器,我会按照以下方式做一些事情:
@JsonCreator
public Data(@JsonProperty("value") final String value) {
this.value = new Value(value);
}
这与你问的有点相反 ;)
我有一个 Value
class 包含一个值:
public class Value {
protected final Object value;
@JsonValue
public Object getValue() {
return value;
}
@JsonCreator
public Value(final Object value) {
this.value = value;
}
}
此 Value
class 作为字段(在其他字段中)嵌入到数据 class:
class Data {
protected final Value value;
@JsonProperty("value")
public Value getValue() {
return value;
}
...
@JsonCreator
public Data(@JsonProperty("value") final Value value, ...) {
this.value = value;
....
}
}
当输入 JSON 对 data
对象的 value
字段有 null
时(参见下面的示例),Data.value
为空。我想将 Data.value
设置为 new Value(null)
。也就是说,数据对象必须持有一个非空值对象,它持有的是null。
{
"value" : null,
...
}
实现此目的最简单的方法是什么?我当然可以更改 Data
的构造函数,但我想知道 Jackson 是否可以自动解决这个问题。
您可以编写自定义反序列化程序并根据您的要求覆盖 getNullValue()
方法,例如
public final class InstantiateOnNullDeserializer
extends JsonNodeDeserializer
{
@Override
public JsonNode getNullValue()
{
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.convertValue(new Value(null), JsonNode.class);
return node;
}
}
并将其注册到您的 Data class
的值字段class Data {
@JsonDeserialize(using = InstantiateOnNullDeserializer.class)
protected final Value value;
@JsonProperty("value")
public Value getValue() {
return value;
}
@JsonCreator
public Data(Value value) {
this.value = value;
}
}
请注意,您需要删除 @JsonProperty("value")
以避免参数类型不匹配。通过删除 JsonProperty 注释,您创建了一个所谓的 "delegate creator",
Jackson 将首先将 JSON 绑定到参数的类型中,然后调用创建者
我认为如果不创建自己的反序列化器或修改构造函数(或 @JsonCreator
),这是不可能的。
来自a good old thread in the Jackson User Group:
@JsonProperty
does not support transformations, since the data binding is based on incremental parsing and does not have access to full tree representation.
因此,为了避免自定义反序列化器,我会按照以下方式做一些事情:
@JsonCreator
public Data(@JsonProperty("value") final String value) {
this.value = new Value(value);
}
这与你问的有点相反 ;)