JSON泛型集合反序列化

Ban*_*nan 5 java spring json generic-collections deserialization

我用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;
}
Run Code Online (Sandbox Code Playgroud)

在我的项目中,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"
            }
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,杰克逊默认将AnswerDto对象的值映射到LinkedHashMap正确(LocationJobTitle)类类型的对象.我应该JsonDeserializer<AnswerDto>使用编写自定义或配置,@JsonTypeInfo并且@JsonSubTypes可能足够吗?

正确地反序列化请求只有一个AnswerDto形式

{
    "uuid": "e82544ac-1cc7-4dbb-bd1d-bdbfe33dee73",
    "type": "LOCATION",
    "value": {
        "text": "Dublin",
        "placeId": "121"
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用:

AnswerDto<Location> answerDto = objectMapper.readValue(jsonRequest, new TypeReference<AnswerDto<Location>>() {
});
Run Code Online (Sandbox Code Playgroud)

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

Ban*_*nan 5

我已经通过使用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;
}
Run Code Online (Sandbox Code Playgroud)