【问题标题】:java/jackson - chained @JsonValue annotations and deserializationjava/jackson - 链式@JsonValue 注释和反序列化
【发布时间】:2015-02-26 02:28:00
【问题描述】:

我有以下结构。我知道这看起来很奇怪,但我正在用这个例子模拟我们的代码:

public static class StringWrapper {
    protected final String s;

    @JsonValue
    public String getS() {
        return s;
    }

    public StringWrapper(final String s) {
        this.s = s;
    }
}

public static class StringWrapperOuter {
    protected final StringWrapper s;

    @JsonValue
    public StringWrapper getS() {
        return s;
    }

    public StringWrapperOuter(final StringWrapper s) {
        this.s = s;
    }
}

public static class POJO {
    protected final List<StringWrapperOuter> data;

    public List<StringWrapperOuter> getData() {
        return data;
    }

    public POJO(final List<StringWrapperOuter> data) {
        this.data = data;
    }

    public POJO() {
        data = Collections.emptyList();
    }
}

POJO 的序列化给出了预期的 JSON 字符串数组:

<mapper>.writeValue(System.out, new POJO(Arrays.asList(new StringWrapperOuter(new StringWrapper("a")), new StringWrapperOuter(new StringWrapper("b")), new StringWrapperOuter(new StringWrapper("c")))));

{"data":["a","b","c"]}

如何将此 JSON 字符串反序列化为 POJO 类型的对象?

<mapper>.readValue("{\"data\":[\"a\",\"b\",\"c\"]}", POJO.class);

映射器难以识别输入,因为两个@JsonValue 注释被链接在一起。它给出了以下例外:

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class StringWrapperOuter] from String value ('a'); no single-String constructor/factory method
 at [Source: {"data":["a","b","c"]}; line: 1, column: 10] (through reference chain: POJO["data"]->java.util.ArrayList[0])

【问题讨论】:

    标签: java jackson deserialization


    【解决方案1】:

    正如 Sotirios 在之前的回答中所说。 @JsonCreator 是这里的关键。但是,为了让所有类都能正常工作,可能需要@JsonProperty

    public static class POJO {
        protected final List<StringWrapperOuter> data;
    
        // In order for POJO creation to work properly the @JsonProperty
        // annotation on the arg is required
        @JsonCreator
        public POJO(@JsonProperty("data") final List<StringWrapperOuter> data) {
            this.data = data;
        }
    
        public List<StringWrapperOuter> getData() {
            return data;
        }
    }
    
    public static class StringWrapper {
        protected final String s;
    
        @JsonCreator
        public StringWrapper(final String s) {
            this.s = s;
        }
    
        @JsonValue
        public String getS() {
            return s;
        }
    }
    
    public static class StringWrapperOuter {
        protected final StringWrapper s;
    
        @JsonCreator
        public StringWrapperOuter(final StringWrapper s) {
            this.s = s;
        }
    
        @JsonValue
        public StringWrapper getS() {
            return s;
        }
    }
    

    【讨论】:

      【解决方案2】:

      @JsonValue 用于序列化。反序列化的类似注解是@JsonCreator

      注释你的构造函数

      @JsonCreator
      public StringWrapper(final String s) {
          this.s = s;
      }
      

      @JsonCreator
      public StringWrapperOuter(final StringWrapper s) {
          this.s = s;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-10
        • 2018-04-04
        • 1970-01-01
        • 1970-01-01
        • 2023-03-04
        相关资源
        最近更新 更多