【问题标题】:Unmarshall JSON to subtypes with different field type jackson将 JSON 解组为具有不同字段类型 jackson 的子类型
【发布时间】:2016-08-23 21:25:27
【问题描述】:

我收到一个 JSON 对象数组,它们都具有 content 字段,但该字段的类型可能不同:

[
    {
        "id": "primaryBodyHeader",
        "type": "RichText",
        "content": "<h1>Alice's Adventures in Wonderland</h1>"
    },
    {
        "id": "1027",
        "type": "RichText",
        "content": {
            "value": "RVMtMTk=",
            "contentType": "DynamicContent"
        }
    }
]

我有豆子:

public abstract class LandingPageContentItem {
    private String id;
    private String type;
    private String content;
}

至少我想在 content 为文本时将其映射到文本字段(非文本内容为 null)

最多,我想根据字段的类型将不同种类的项目映射到不同的子类内容 - TextContentItem,ComplexContentItem 等等。 @JsonSubTypes 不能这样做

有没有办法在没有自定义反序列化器的情况下做到这一点?

【问题讨论】:

    标签: java json jackson json-deserialization


    【解决方案1】:

    如果您不知道(或无法控制)content 字段中可能包含的内容,那么我建议您像这样映射原始 com.fasterxml.jackson.databind.JsonNode

    public static class LandingPageContentItem {
        private final String id;
        private final String type;
        private final JsonNode content;
    
        @JsonCreator
        public LandingPageContentItem(
                @JsonProperty("id") final String id, 
                @JsonProperty("type") final String type, 
                @JsonProperty("content") final JsonNode content) {
            this.id = id;
            this.type = type;
            this.content = content;
        }
    
        /* some logic here */
    }
    

    然后就可以正常阅读了

    ObjectMapper mapper = new ObjectMapper();
    List<LandingPageContentItem> items = 
        mapper.readValue(node, new TypeReference<List<LandingPageContentItem>>() {});
    

    稍后您可以验证JsonNode 是否属于预期类型。

    if (content.isTextual()) {
        // do something with content.asText(); 
    }
    

    【讨论】:

      【解决方案2】:

      不写自定义反序列化器,我能想到的最好的就是:

      public class LandingPageContentItem {
          private String id;
          private String type;
          private Object content;
      }
      

      然后只需使用if(item.content instanceof String)if(item.content instanceof Map) 从那里处理它。

      【讨论】:

      • @vsminkov 有更好的答案。在大多数情况下,JsonNode 可能比 Object 更好。
      猜你喜欢
      • 1970-01-01
      • 2021-05-09
      • 2020-10-14
      • 2021-01-08
      • 1970-01-01
      • 2017-01-30
      • 2017-03-27
      • 1970-01-01
      • 2020-02-27
      相关资源
      最近更新 更多