java / jackson - @ JsonValue / @ JsonCreator和null

时间:2015-01-13 11:07:42

标签: java json null jackson wrapper

我有一个Value类,其中包含一个值:

public class Value {
    protected final Object value;

    @JsonValue
    public Object getValue() {
        return value;
    }

    @JsonCreator
    public Value(final Object value) {
        this.value = value;
    }
}

Value类作为字段(在其他字段中)嵌入数据类中:

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对null对象的value字段有data(例如,请参见下文),则Data.value为空。我希望将Data.value设置为new Value(null)。换句话说,数据对象必须包含一个非空值对象,该对象保存空值。

{
  "value" : null,
  ...
}

实现这一目标的最简单方法是什么?我可以改变Data的构造函数,但我想知道杰克逊是否可以自动解决这个问题。

2 个答案:

答案 0 :(得分:2)

您可以编写自定义反序列化器并根据您的要求覆盖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 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 注释,您可以创建一个所谓的"委托创建者", 杰克逊首先将JSON绑定到参数类型,然后调用创建者

答案 1 :(得分:1)

如果不创建自己的反序列化程序或修改构造函数(或@JsonCreator),我不相信这是可能的。

来自a good old thread in the Jackson User Group

  

@JsonProperty不支持转换,因为数据绑定基于增量解析,并且无法访问完整树表示。

因此,为了避免使用自定义反序列化器,我会按照以下方式执行以下操作:

@JsonCreator
public Data(@JsonProperty("value") final String value) {
    this.value = new Value(value);
}

这与你提出的要求相反;)