编程语言
首页 > 编程语言> > java – JSON泛型集合反序列化

java – JSON泛型集合反序列化

作者:互联网

我用Java编写了这样的DTO类:

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;
}

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

如何配置AnswersDto(使用特殊注释)或AnswerDto(注释)类,以便能够在其正文中使用AnswersDto正确反序列化请求,例如:

{
    "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"
            }
        }
    ]
}

不幸的是,Jackson默认将AnswerDto对象的值映射到LinkedHashMap而不是正确的(Location或JobTitle)类类型的对象.
我应该编写自定义JsonDeserializer< AnswerDto>或使用@JsonTypeInfo和@JsonSubTypes配置就足够了?

仅使用一个AnswerDto正确地反序列化请求

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

我正在使用:

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

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

最佳答案:

我已经通过使用Jackson的自定义注释@JsonTypeInfo和@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,java,spring,deserialization,generic-collections
来源: https://codeday.me/bug/20190516/1114994.html