SpringBoot -- 请求数据多态映射(jackson)

news2024/10/7 10:16:09

有些情况下,服务端提供了一个抽象类及其多个实现类,当前端传递 json 数据到后端时,我们希望映射得到的对象数据是根据某个特征区分开的具体的实现类对象。

文章目录

      • 实现方式
      • 示例
        • 抽象类对象
        • 若干实现类
        • 测试接口及前端传递请求体
        • 接参结果
      • @JsonTypeInfo 和 @JsonSubTypes
        • 其他常用映射方式
          • 1__ 指定对象类型(两种方式)
          • 2__自定义序列化、反序列化方式

实现方式

可以通过 jackson 实现序列化及反序列化,并使用 jackson 包中的
@JsonTypeInfo @JsonSubTypes 这两个注解,去实现该功能

示例

抽象类对象
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, visible = true, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = DncCheckBox.class, name = "CHECKBOX"),
        @JsonSubTypes.Type(value = DncDate.class, name = "DATE"),
        @JsonSubTypes.Type(value = DncInputNumber.class, name = "INPUTNUMBER"),
        @JsonSubTypes.Type(value = DncSerialNumber.class, name = "SERIALNUMBER"),
        @JsonSubTypes.Type(value = DncText.class, name = "TEXT")
})
public abstract class DocNoComponent {
    public String type; //类型

    public void setType(String type) {
        this.type = type;
    }
    
    public String getType() {
        return type;
    }
}
若干实现类
public class DncCheckBox extends DocNoComponent {
    public DncCheckBox() {
        super();
    }
}
public class DncDate extends DocNoComponent {
    public DncDate() {
        super();
    }
}
public class DncInputNumber extends DocNoComponent {
    public DncInputNumber() {
        super();
    }
}
测试接口及前端传递请求体
@PostMapping("/test00091")
public void test00091(@RequestBody List<DocNoComponent> configItems){
    System.out.println(configItems);
}
[
    {
        "type": "TEXT"
    },
    {
        "type": "DATE"
    },
    {
        "type": "INPUTNUMBER"
    }
]
接参结果

在这里插入图片描述

@JsonTypeInfo 和 @JsonSubTypes

以上的方式我们是通过根据对象中的某个属性,判断反序列化时应该反序列化为那种类型的对象,如果不配置 property 字段,默认读取 json 对象中的 @type 属性
在这里插入图片描述

其他常用映射方式
1__ 指定对象类型(两种方式)

use=JsonTypeInfo.Id.CLASS 通过 json 数据中的 @class 属性指定目标对象的全限定类型路径,property 可以不赋值,默认读取 @class 属性。
use=JsonTypeInfo.Id.MINIMAL_CLASS 通过 json 数据中的 @c 属性指定目标对象的全限定类型路径,property 可以不赋值,默认读取 @c属性。

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
//@JsonTypeInfo(use=JsonTypeInfo.Id.MINIMAL_CLASS, include=JsonTypeInfo.As.PROPERTY, property="@c")
public abstract class DocNoComponent { 
	...
}
{
  "@class" : "com.***.DncDate",
  "type" : "DATE"
}

在这里插入图片描述

2__自定义序列化、反序列化方式

use = JsonTypeInfo.Id.CUSTOM 配合 @JsonTypeIdResolver 使用
自定义解析器里面,对于反序列化,我们主要关注实现 typeFromId 这个方法,
在这里我们通过接收到的 @no 属性去判断映射为具体对象

@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, include = JsonTypeInfo.As.EXISTING_PROPERTY, visible = true, property = "@no")
@JsonTypeIdResolver(DocNoComponentTypeIdResolver.class)
public abstract class DocNoComponent {
...
}
public class DocNoComponentTypeIdResolver implements TypeIdResolver {
    private JavaType baseType;

    @Override
    public void init(JavaType javaType) {
        baseType = javaType;
    }


    @Override
    public String idFromValue(Object o) {
        return idFromValueAndType(o, o.getClass());
    }


    @Override
    public String idFromValueAndType(Object o, Class<?> aClass) {
        String name = aClass.getName();
        String[] splits = StringUtils.split(name, ".");
        String className = splits[splits.length - 1];
        return className;
    }


    @SneakyThrows
    @Override
    public JavaType typeFromId(DatabindContext databindContext, String type) {
        Class clazz = null;
        switch(type){
            case "1":
                clazz = Class.forName("com.***.DncCheckBox");
                break;
            case "2":
                clazz = Class.forName("com.***.DncDate");
                break;
            case "3":
                clazz = Class.forName("com.***.DncInputNumber");
                break;
            default:
                break;
        }
        if (clazz == null) {
            throw new IllegalStateException("cannot find class '" + type + "'");
        }
        return databindContext.constructSpecializedType(baseType, clazz);
    }

    @Override
    public String idFromBaseType() {
        return idFromValueAndType(null, baseType.getClass());
    }

    @Override
    public String getDescForKnownTypeIds() {
        return null;
    }

    @Override
    public JsonTypeInfo.Id getMechanism() {
        return JsonTypeInfo.Id.CUSTOM;
    }
}
[
    {
        "@no":"2",
        "type": "TEXT"
    }
]

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1155672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript的高级概述

还记得我们刚刚开始的时候给JavaScript的定义吗&#xff1f; JavaScript是一种高级的&#xff0c;面向对象的&#xff0c;多范式变成语言&#xff01; 这种定义JavaScript只是冰山一角&#xff01; JavaScript的高级定义 JavaScript是一种高级的、基于原型的、面向对象、多范…

node使用fs模块(二)—— 读取文件的基本使用(普通读取、同步读取等、流式读取)

文章目录 一、读取文件1. 参数说明2. 基本使用3.读取文件的同步和异步 二、流式文件写入&#xff08;fs.appendFile&#xff09;1. 参数说明2.基本使用 一、读取文件 1. 参数说明 参数1&#xff1a; path——读取的文件路径&#xff08;必填&#xff09; 参数2&#xff1a; op…

怎么在电脑桌面上添加待办事项?

在电脑桌面上选择一款待办事项工具&#xff0c;可以高效率地督促各项任务的按时完成&#xff0c;大大地提高工作的效率&#xff0c;支持在电脑上安装待办事项的工具类型是比较多的&#xff0c;为更好的辅助日常办公&#xff0c;建议大家可以选择高效率辅助办公的电脑便签工具&a…

leetcode:374. 猜数字大小(二分查找)

一、题目 函数原型&#xff1a;int guessNumber(int n) 二、思路 本题其实就是从 1 - n 中找出所要的答案。利用guess函数来判断数字是否符合答案。 答案小于当前数字&#xff0c;guess函数返回-1 答案等于当前数字&#xff0c;guess函数返回0 答案大于当前数字&#xff0c;gue…

会自动写代码的AI大模型来了!阿里云推出智能编码助手通义灵码

用大模型写代码是什么样的体验&#xff1f;10月31日&#xff0c;杭州云栖大会上&#xff0c;阿里云对外展示了一款可自动编写代码的 AI 助手&#xff0c;在编码软件的对话窗口输入“帮我用 python 写一个飞机游戏”&#xff0c;短短几秒&#xff0c;这款名为“通义灵码”的 AI …

10月31日星期二今日早报简报微语报早读

10月31日星期二&#xff0c;农历九月十七&#xff0c;早报微语早读分享。 1、广西官宣&#xff1a;做试管婴儿费用可报销&#xff1b; 2、港媒&#xff1a;4名港大学生承认“煽惑他人蓄意伤人罪”&#xff0c;被判监禁2年&#xff1b; 3、331名中国维和官兵全部获联合国勋章…

广告电商——边看广告边赚钱,实现三方共赢的局面

购物能赚钱&#xff1f;你相信嘛&#xff1f;广告电商模式边购物边赚钱&#xff0c;每天看看广告就能赚钱&#xff0c;白嫖 零撸 我之前有个客户就用了这种模式&#xff0c;购物的积分&#xff0c;然后用户看广告释放积分来赚钱&#xff0c;因为广告都是我们对接好了的一些头部…

【SOC基础】单片机学习案例汇总 Part2:蜂鸣器、数码管显示

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

FreeRTOS深入教程(队列内部机制和源码分析)

文章目录 前言一、队列结构体分析二、创建队列三、读写队列源码分析1.读队列源码分析2.写队列源码分析 总结 前言 本篇文章主要来为大家分析队列的内部机制和源码实现。 一、队列结构体分析 在FreeRTOS中队列会使用一个结构体来表示&#xff1a; 1.int8_t * pcHead 和 int…

MySQL数据库的存储引擎,底层存储结构,事物隔离级别,索引,日志等

存储引擎 存储引擎就是存储数据、建立索引、更新/查询数据等技术的实现方式。存储引擎是基于表而不是基于库的&#xff0c;所以存储引擎也可以被称为表引擎。 默认存储引擎是InnoDB。 InnoDB 在 MySQL 5.5 之后&#xff0c;InnoDB 是默认的 MySQL 引擎。 1.支持事务 2.行级锁…

YOLOv5/YOLOv7改进: AIFI (尺度内特征交互)助力YOLO | YOLO终结者?RT-DETR一探究竟

💡💡💡本文全网首发独家改进: AIFI (尺度内特征交互)助力YOLO ,提升尺度内和尺度间特征交互能力,同时降低多个尺度的特征之间进行注意力运算,计算消耗较大等问题 推荐指数:五星 AIFI | 亲测在多个数据集能够实现涨点 💡💡💡Yolov5/Yolov7魔术师,独家首…

Windows11无法打开Photoshop CC 2017问题解决

情况描述&#xff1a; Windows11上&#xff0c;双击Photoshop CC 2017没反应 解决办法&#xff1a; 此时需要启动Windows的“事件查看器”来确认问题出在哪里。可以直接通过开始菜单搜索启动&#xff0c;也可以通过右键点击“此电脑”->“管理”&#xff0c;然后找到事件查…

解密杭州亚运背后科技:核心系统100%上云,20多项全球首创智能应用

10月31日&#xff0c;2023杭州云栖大会&#xff0c;杭州亚运会信息技术中心执行指挥长、杭州亚组委广播电视和信息技术部副部长张鸽以《科技创新在亚运舞台精彩绽放》为主题&#xff0c;分享了杭州亚运会的智能亚运实践。 杭州亚运会打造了史上首个全覆盖的数字化服务体系&…

港府Web3宣言周年思考:合规困境中的“隐患”

出品&#xff5c;欧科云链研究院 作者&#xff5c;毕良寰 距离《有关虚拟资产在港发展的政策宣言》已过去一年&#xff0c;我们欧科云链研究院在分析全球几个主要国家和地区对Web3的监管政策及态度后&#xff0c;对港府的雄心壮志充满期待。然而&#xff0c;由于近期一些庞氏骗…

学习redis之前的泛泛而谈(特性介绍,应用场景,Ubuntu安装与通用命令介绍)

文章目录 前言关于分布式系统Redis特性Redis应用场景Redis5安装redis命令最核心的两个命令&#xff1a;get和setkeysexitsdelexpirettlredis中key的过期策略type redis数据类型的内部实现方式redis的单线程 前言 redis最重要的概念&#xff1a;在内存中存储数据 为什么要设计一…

MySQL(4):运算符

算术运算符 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达式&#xff0c;对数值或表达式进行加&#xff08;&#xff09;、减&#xff08;-&#xff09;、乘&#xff08;*&#xff09;、除&#xff08;/&#xff09;和取模&#xff08;%&#…

在uni-app中使用ECharts - 配置四种不同的图表

&#x1f468;‍&#x1f9b0;博主&#xff1a;小猫娃来啦 &#x1f468;‍&#x1f9b0;文章核心&#xff1a;在uni-app中使用ECharts - 配置四种不同的图表 文章目录 前言安装ECharts插件引入ECharts库创建Charts实例和图表容器配置和渲染图表配置柱状图配置折线图配置饼图配…

详解final, abstract, interface关键字

一.final关键字 1.final关键字介绍 ——final关键字可以去修饰类、方法、属性和局部变量 2.final关键字的作用 1&#xff09;final修饰类&#xff0c;这个类不能被其他类继承 2&#xff09;final修饰方法&#xff0c;方法不能被重写 3&#xff09;final修饰属性&#xff0c;属…

通过shiro框架记录用户登录,登出及浏览器关闭日志

背景&#xff1a; 公司项目之前使用websocket记录用户登录登出日志及浏览器关闭记录用户登出日志&#xff0c;测试发现仍然存在问题&#xff0c; 问题一&#xff1a;当浏览器每次刷新时websocket其实是会断开重新连接的&#xff0c;因此刷新一下就触发记录登出的日志&#xff0…

41.排序练习题(王道2023数据结构第8章综合练习)

试题1&#xff08;王道8.3.3节综合练习2&#xff09;&#xff1a; 编写双向冒泡排序算法&#xff0c;在正反两个方向交替扫描。即第一趟把关键字最大的元素放在序列的最后面&#xff0c;第二趟把关键字最小的元素放在序列最前面&#xff0c;如此反复。 首先实现冒泡排序&…