【问题标题】:Why is the Jackson Object Mapper unable to deserialize this nested JSON?为什么杰克逊对象映射器无法反序列化这个嵌套的 JSON?
【发布时间】:2018-07-04 23:15:07
【问题描述】:

我正在更新一些代码以使用新的 API,该 API 返回相同类型的数据但采用不同的 JSON 格式。这是请求返回的示例:

{
    "code": 200,
    "message": "OK",
    "data": [
        {
            "start_time": "2017-09-20T00:00:00.000-04:00",
            "end_time": "2017-09-21T00:00:00.000-04:00",
            "value": 8612.637512577203
        },
        {
            "start_time": "2017-09-21T00:00:00.000-04:00",
            "end_time": "2017-09-22T00:00:00.000-04:00",
            "value": 8597.89155775999
        },
        {
            "start_time": "2017-09-22T00:00:00.000-04:00",
            "end_time": "2017-09-23T00:00:00.000-04:00",
            "value": 24584.603303989123
        }
    ],
    "meta": {
        "space_id": "e1c38410-f912-4ae3-9db9-10a1ad1e3bf5",
        "channel_id": 1,
        "aggregation_type": "period_beginning",
        "pids_count": 1,
        "timezone": "America/New_York"
    }
}

我想忽略代码和消息属性,并将数据数组放入映射中的列表中,键是“space_id”属性(Map<String, List<Reading>>),以便与旧实现兼容。这是我创建的包含反序列化对象的 POJO:

@JsonIgnoreProperties({"code", "message", "meta"})
public class GetReadingsResult {

    @JsonIgnore
    private Map<String, List<Reading>> readings;

    @JsonIgnore
    public GetReadingsResult(Map<String, List<Reading>> readings) {
        this.readings = readings;
    }

    @JsonCreator
    public GetReadingsResult(@JsonProperty("data")Reading[] data, @JsonProperty("space_id")String spaceId) {
        this.readings.put(spaceId, Arrays.asList(data));
    }

    //...other getters and setters...
}

在我的测试中,我在测试 JSON 文件上调用 readValue 并收到以下错误:

com.fasterxml.jackson.databind.JsonMappingException: Instantiation of [simple type, class model.GetReadingsResult] value failed: null

设置/注释我的 POJO 以处理此嵌套文件的正确方法是什么?

【问题讨论】:

  • 根 JSON 对象没有 space_id。如果你想要那个值,你需要解析 meta 对象。
  • 那么如何解析不是根对象的对象?
  • 您已经在使用Reading,不是吗?删除meta 的忽略,将其解析为一个对象,然后从该对象中提取值。

标签: java json jackson


【解决方案1】:

这是正确的实现方式。

请注意所有事物的对象观点:

这些是pojo:

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "start_time",
    "end_time",
    "value"
})
public class Datum {

    @JsonProperty("start_time")
    public String startTime;
    @JsonProperty("end_time")
    public String endTime;
    @JsonProperty("value")
    public Double value;

}


import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "space_id",
    "channel_id",
    "aggregation_type",
    "pids_count",
    "timezone"
})
public class Meta {

    @JsonProperty("space_id")
    public String spaceId;
    @JsonProperty("channel_id")
    public Integer channelId;
    @JsonProperty("aggregation_type")
    public String aggregationType;
    @JsonProperty("pids_count")
    public Integer pidsCount;
    @JsonProperty("timezone")
    public String timezone;

}

这是包装器根对象:

import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "code",
    "message",
    "data",
    "meta"
})
public class ExampleStack {

    @JsonProperty("code")
    public Integer code;
    @JsonProperty("message")
    public String message;
    @JsonProperty("data")
    public List<Datum> data = null;
    @JsonProperty("meta")
    public Meta meta;

}

这是一个有效的例子:

import com.fasterxml.jackson.databind.ObjectMapper;//<--IMPORTANT!

public class TestJacksonObject {


     public static void main(String[] args) {


         ObjectMapper mapper =  new ObjectMapper(); 
         ExampleStack stack = null;
            try {
                stack = mapper .readValue( new FileInputStream(new File("C://test.json")) , ExampleStack.class);

            } catch (IOException e) {
                e.printStackTrace();
            }

    System.out.println(stack.message);//<--Do whatever you want...
.....

如果生成所有这些类太难了,这实际上很乏味,我建议你通过这个有用的网站在线自动生成它们:

Json2Pojo

希望对你有所帮助!

【讨论】:

  • 感谢您的详尽回答!
猜你喜欢
  • 2019-11-15
  • 2016-12-07
  • 2012-11-19
  • 2021-10-02
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
  • 2016-01-14
  • 2020-06-01
相关资源
最近更新 更多