Unmarshall JSON 到具有不同字段类型 jackson 的子类型

Unmarshall JSON to subtypes with different field type jackson

我收到一个 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)

顶多是想根据字段的类型将不同种类的item映射到不同的子类content——TextContentItem,ComplexContentItem之类的。 @JsonSubTypes 不能这样做

有没有不用自定义解串器的方法?

在不编写自定义反序列化器的情况下,我能想到的最好的是:

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

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

如果您不知道(或无法控制)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(); 
}