【问题标题】:Java, How can I use Jackson ObjectMapper to deserialize a double nested json listJava,如何使用 Jackson ObjectMapper 反序列化双嵌套 json 列表
【发布时间】:2018-03-27 19:14:55
【问题描述】:

我正在尝试反序列化具有以下结构的 json 对象:

{"results":{  
  "Assessments":{  
     "Assessment":[  
        {  
           "assessor":"",
           "buildingName":"Emerald Palace Project",
           "certBody":"",
           ...

顶层是一个名为“results”的单一实体,其中包含“assessments”,它们只是“assessment”的列表/数组。

我尝试了多种映射器配置组合,例如:

        ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.configure(DeserializationConfig.Feature.UNWRAP_ROOT_VALUE, true);

但无论我如何切换它,我都会得到一个带有空评估的结果对象。

这是我使用 Lombok 的对象类。

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
static class Results {
    private Assessments assessments;
}

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
static class Assessments {
    private List<Assessment> assessments;
}

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Assessment {
    private int parentId;
    private String stage;
    private String notes;
    private String rating;
    private String scheme;
}

我觉得我一定少了一块。

任何见解将不胜感激。

【问题讨论】:

    标签: java json jackson objectmapper


    【解决方案1】:

    明确一点:你写的

    […] “评估”只是“评估”的列表/数组。

    您的 POJO 反映了这一点……那么您的 JSON 必须是……

    {"results":{  
        "Assessments":{  
            [  
                {  
                    "assessor":"",
                    "buildingName":"Emerald Palace Project",
                    "certBody":"",
                    ...
    

    …而不是…

    {"results":{  
        "Assessments":{  
            "Assessment":[  
                {  
                    "assessor":"",
                    "buildingName":"Emerald Palace Project",
                    "certBody":"",
                    ...
    

    注意直接在“评估”中的列表。 另请注意,您的 POJO 字段是小写的,因此必须是您的 JSON 键。

    所以要将 POJO 与 JSON 匹配,您有多种选择:

    • 将您的 JSON 密钥更改为小写和驼峰式
    • 使用 @JsonProperty("field-name") 匹配您的 JSON 密钥

    但在每种情况下,您都必须了解当前关于评估/评估列表的冲突。

    【讨论】:

    • 感谢您向前迈出的一步。更改 json 确实有效,但是我收到的是来自第三方 API 的内容,因此无法更改。但这个提示确实让我朝着正确的方向前进,谢谢。
    • 通常也可以添加中间层来匹配结构。这会导致不必要的层,但通常会简化建模。
    【解决方案2】:

    因此,因为我必须使用第三方 API 提供给我的 json,所以无法更改 json。

    我是这样工作的。

    首先,我必须将 Assessments 对象更改为具有单数名称的列表。 “assessment”而不是“assessments”,因为它在 json 响应中是这样拼写的。

    @Getter
    @Setter
    @NoArgsConstructor
    static class Assessments {
        private List<Assessment> assessment;
    }
    

    我还将我的 ObjectMapper 设置为忽略大小写和未知属性。确保使用 com.fasterxml.jackson.databind.ObjectMapper。

    private static ObjectMapper getJsonMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
        return mapper;
    }
    

    然而,最大的变化是引入了一个容器类。

    @Getter
    @Setter
    @NoArgsConstructor
    private static class JsonContainer {
        private Results results;
    }
    

    这个类是必需的,因为它包含顶级 json 对象“结果”。

    完成这些更改后,我的 Java 对象处于我预期的状态。

    【讨论】:

      猜你喜欢
      • 2018-07-24
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 1970-01-01
      • 2019-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多