Jackson处理抽象类的序列化和反序列化

Jackson处理抽象类的序列化和反序列化

需求

现在有这样的需求:

  1. 在controller接口层,@RequestBody接收的是抽象类,@ResponseBody也是抽象类。controller根据请求参数反序列化成子类对象,返回时返回子类对象。
  2. MongoDB在新增数据时使用的是抽象类,查询返回结果也是抽象类。

默认情况,抽象类是无法完成序列化和反序列化的。那怎么实现呢?

现在有这样的类结果:

在这里插入图片描述

controller方法

@PostMapping
public ResponseEntity add(@RequestBody AbstractItem abstractItem) {
    AbstractItem item = itemService.add(abstractItem);
    return ResponseEntity.ok(item);
}

MongoDb新增

public AbstractItem findById(String id) {
    return mongoTemplate.findById(id, AbstractItem.class);
}

实现

这时候就用到了@JsonTypeInfouse属性表示使用哪种信息来作为 Json 对应的实际子类的标识符和@JsonSubTypes注解来指定逻辑名称和子类的映射关系.

如下所示:

@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
        @JsonSubTypes.Type(value = DefaultItem.class, name = "item"),
        @JsonSubTypes.Type(value = DefaultLayoutRow.class, name = "row"),
})
public abstract class AbstractItem implements Item {
    @Id
    private String id;
    private String name;
}
@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
@JsonSubTypes({
        @JsonSubTypes.Type(value = DefaultLayoutRow.class, name = "row")
})
public abstract class AbstractLayoutRow extends AbstractItem implements LayoutRow {
    private Integer gutter;

    public AbstractLayoutRow() {
    }

    public AbstractLayoutRow(int gutter) {
        this.gutter = gutter;
    }
}
@Data
@NoArgsConstructor
@JsonTypeName(value = "item")
@Document(collection = "form_item")
@CompoundIndexes(@CompoundIndex(def = "{'group': 1}"))
public class DefaultItem extends AbstractItem {

    @ApiModelProperty("标签名")
    private String label;
    @ApiModelProperty(value = "模型", notes = "字段存值的key,及v-model的值")
    private String model;
    private String desc;
@JsonTypeName(value = "row")
public class DefaultLayoutRow extends AbstractLayoutRow {
    private List<AbstractLayoutCol> columns;

    public DefaultLayoutRow() {
    }

    public DefaultLayoutRow(List<AbstractLayoutCol> columns) {
        this.columns = columns;
    }

    public DefaultLayoutRow(int gutter, List<AbstractLayoutCol> columns) {
        super(gutter);
        this.columns = columns;
    }

    public List<AbstractLayoutCol> getColumns() {
        return columns;
    }

    public void setColumns(List<AbstractLayoutCol> columns) {
        this.columns = columns;
    }
}

JsonTypeInfo.Id

public static enum Id {
    NONE((String)null),
    CLASS("@class"),
    MINIMAL_CLASS("@c"),
    NAME("@type"),
    CUSTOM((String)null);
}

有五种类型。

  1. CLASS("@class"): 表示使用权限定类名来表示Json对应的类型,并且会在序列化的Json中插入一个key为@class的信息,值为类的全限定名。
  2. MINIMAL_CLASS("@c"): 与Class不同,它不适用全限定名,而是根据子类来计算出应该是使用单纯的类名,还是包含一部分的包名,并且最终的值前会加一个“.” 。
  3. NAME("@type"):标识表示使用逻辑名称标识Json对应的类型。默认是类名。也可以使用@JsonSubTypes注解 来指定逻辑名称和子类的映射关系。@JsonSubTypes.Type 注解的 name 属性没有指定时,Jackson 会查找这个类上的 @JsonTypeName 注解的值用作 name ;如果也不存在,就会使用类名。

参考:https://blog.csdn.net/weixin_33574009/article/details/113491273

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超人@不会飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值