JSON通用集合反序列化 [英] JSON generic collection deserialization

查看:166
本文介绍了JSON通用集合反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有用Java编写的DTO类:

I've such DTO classes written in Java:

public class AnswersDto {
    private String uuid;
    private Set<AnswerDto> answers;
}

public class AnswerDto<T> {
    private String uuid;
    private AnswerType type;
    private T value;
}

class LocationAnswerDto extends AnswerDto<Location> {
}

class JobTitleAnswerDto extends AnswerDto<JobTitle> {
}

public enum AnswerType {
    LOCATION,
    JOB_TITLE,
}

class Location {
    String text;
    String placeId;
}

class JobTitle {
    String id;
    String name;
}

在我的项目中,有用于对JSON进行序列化和反序列化的Jackson库.

In my project there is Jackson library used for serialization and deserialization of JSONs.

如何配置AnswersDto(使用特殊注释)或AnswerDto(也包括注释)类,以便能够使用主体中的AnswersDto正确反序列化请求,例如:

How to configure AnswersDto (use special annotations) or AnswerDto (annotation as well) classes to be able to properly deserialize request with AnswersDto in its body, e.g.:

{
    "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73",
    "answers": [
        {
            "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73",
            "type": "LOCATION",
            "value": {
                "text": "Dublin",
                "placeId": "121"
            }
        },
        {
            "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73",
            "type": "JOB_TITLE",
            "value": {
                "id": "1",
                "name": "Developer"
            }
        }
    ]
}

不幸的是,默认情况下,杰克逊将AnswerDto对象的值映射到LinkedHashMap而不是适当的(LocationJobTitle)类类型的对象. 我应该编写自定义JsonDeserializer<AnswerDto>还是使用@JsonTypeInfo@JsonSubTypes进行配置就足够了?

Unfortunately Jackson by default maps value of AnswerDto object to LinkedHashMap instead of object of proper (Location or JobTitle) class type. Should I write custom JsonDeserializer<AnswerDto> or configuration by use of @JsonTypeInfo and @JsonSubTypes could be enough?

仅以一个AnswerDto的形式正确反序列化请求

To properly deserialize request with just one AnswerDto in form of

{
    "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73",
    "type": "LOCATION",
    "value": {
        "text": "Dublin",
        "placeId": "121"
    }
}

我正在使用:

AnswerDto<Location> answerDto = objectMapper.readValue(jsonRequest, new TypeReference<AnswerDto<Location>>() {
});

没有任何其他自定义配置.

without any other custom configuration.

推荐答案

我已经通过使用Jackson的自定义批注@JsonTypeInfo@JsonSubTypes解决了问题:

I've resolved issue by using Jackson's custom annotations @JsonTypeInfo and @JsonSubTypes:

public class AnswerDto<T> {

    private String uuid;

    private AnswerType type;

    @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
    @JsonSubTypes({
            @JsonSubTypes.Type(value = Location.class, name = AnswerType.Types.LOCATION),
            @JsonSubTypes.Type(value = JobTitle.class, name = AnswerType.Types.JOB_TITLE)
    })
    private T value;
}

这篇关于JSON通用集合反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆