【问题标题】:How to learn Jackson to cast inheritors of abstract class?如何学习杰克逊铸造抽象类的继承者?
【发布时间】:2019-10-17 03:39:04
【问题描述】:

我有一堂课:

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

    private List<AbstractFieldDto> fields;
}

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

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

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

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

控制器:

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

当 Jackson 尝试解析 AppealTemplateDto 时,它会崩溃并出现异常:

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

据我了解,Jackson 无法定义如何投射传入的AbstractFieldDto。请教我,该怎么办?

【问题讨论】:

  • 添加默认构造函数。

标签: java jackson


【解决方案1】:

您需要的注释是:

@JsonTypeInfo
@JsonSubType

@JsonTypeName

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

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

【讨论】:

    猜你喜欢
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多