【问题标题】:java/jackson - @JsonValue/@JsonCreator and nulljava/jackson - @JsonValue/@JsonCreator 和 null
【发布时间】:2015-01-13 11:07:41
【问题描述】:

我有一个 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 具有 value 字段的 data 对象的 null 时(参见下面的示例),Data.value 为空。我想将Data.value 设置为new Value(null)。换句话说,数据对象必须持有一个非空值对象,该对象持有空值。

{
  "value" : null,
  ...
}

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

【问题讨论】:

    标签: java json null jackson wrapper


    【解决方案1】:

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

    【讨论】:

    • 谢谢。我将编写一个自定义反序列化器。这对 ctr 也有效吗? public Data(@JsonProperty("value") @JsonDeserialize(using = InstantiateOnNullDeserializer.class) Value value) { ... } 并从 getter 中删除 @JsonDeserialize 注释。将反序列化器与 ctr/@JsonCreator 链接对我来说更有意义。
    • 其实应该在现场,在答案中编辑。我认为只有在字段或访问器方法上设置时才会应用反序列化器。记得从构造函数中删除@JsonProperty
    【解决方案2】:

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

    来自a good old thread in the Jackson User Group

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

    所以,为了避免使用自定义反序列化器,我会按照以下方式做一些事情:

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

    这与您的要求相反;)

    【讨论】:

      猜你喜欢
      • 2015-02-26
      • 2018-03-21
      • 2019-06-23
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 2020-03-17
      • 2020-03-26
      • 1970-01-01
      相关资源
      最近更新 更多