如何学习杰克逊铸造抽象类的继承者? [英] How to learn Jackson to cast inheritors of abstract class?

查看:53
本文介绍了如何学习杰克逊铸造抽象类的继承者?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堂课

@EqualsAndHashCode(callSuper = true)
@Data
public class AppealTemplateDto extends AbstractDto {

    private List<AbstractFieldDto> fields;
}

此类包含 AbstractFieldDto 继承者的列表,例如:

This class contains list of AbstractFieldDto inheritors, e.g.:

@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
public class InputFieldDto extends AbstractFieldDto {

    private String fieldType = FieldType.INPUT.name();
    private String text;
}

总共有近6-7个继承者,&AbstractTemplateDto可以包含任何一组.

Totally, there are near 6-7 inheritors, & AbstractTemplateDto may contain any set of them.

控制器:

@PostMapping
public ResponseEntity<AppealTemplateDto> create(@RequestBody AppealTemplateDto dto) {
    return ResponseEntity.ok(service.save(dto));
}

当Jackson尝试解析 AppealTemplateDto 时,它崩溃并发生异常:

When Jackson trying to parse AppealTemplateDto, it crashes with exception:

起因:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造的实例 ru.appeal.template.dto.field.AbstractFieldDto (不存在创建者,例如默认构造):抽象类型需要映射到具体类型,具有自定义反序列化器,或包含其他类型信息

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of ru.appeal.template.dto.field.AbstractFieldDto (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information

据我了解,Jackson无法定义如何将传入的 AbstractFieldDto强制转换为.请给我建议,该怎么办?

As I understand, Jackson can't define, how to cast incoming AbstractFieldDto. Please, advice me, what to do?

推荐答案

您需要的注释是:

@JsonTypeInfo
@JsonSubType

@JsonTypeName

一些解释:如果您有很多抽象类型的实现,Jackson不能猜测您的json是哪种类型,则需要在json中添加类型名称,例如作为新属性(这是一种策略)):

Some explanation: if you have many implementation of your abstract type, Jackson can't guess which type is your json, you need to add a type name in json, for example as a new property (this is one of the strategies):

//tell to jackson where to find the type name
@JsonTypeInfo(   use = JsonTypeInfo.Id.NAME, include = As.PROPERTY, property = "type")
// tell to jackson the implementations to scan
@JsonSubTypes({
    @JsonSubTypes.Type(value = InputFieldDto.class, name = "input")
    //, ...
})
public class AbstractFieldDto {
}

//tell to jackson what is the type name in json
@JsonTypeName("input")
public class InputFieldDto extends AbstractFieldDto {

    private String fieldType = FieldType.INPUT.name();
    private String text;
}

这篇关于如何学习杰克逊铸造抽象类的继承者?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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