【工作中问题解决实践 十二】使用@JsonTypeInfo实现请求数据对象多态

news2024/12/22 20:04:17

最近在处理接口请求进行数据写入的一个case时,我希望上游只使用我一个写入接口去实现不同类型的数据写入,而上游的数据写入Model是各不相同的,这就要求我接口的一个对象可以应对上游不同类型对象的写入请求。关于Jackson的概念不再赘述,参照这篇Blog:【Spring MVC学习笔记 五】SpringMVC框架整合Jackson工具

模拟代码实现示例

为了代码保密,同样用示例的方式进行介绍

基类及子类

接收请求的基类

package com.example.springboot.controller.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;

import java.time.LocalDateTime;

/**
 * @author tianmaolin004
 * @date 2023/8/14
 */
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "sceneCode", visible = true)
@JsonSubTypes(value = {
        @JsonSubTypes.Type(value = JmBrandEnterSceneModel.class, name = "JmBrandEnterSceneModel"),
        @JsonSubTypes.Type(value = JmsEnterSceneModel.class, name = "JmsEnterSceneModel")
})
@Data
public class SceneModel {
    /**
     * 场景名称
     */
    private String sceneCode;
    /**
     * 场景时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime sceneTime;
    /**
     * 请求数据来源
     */
    private String requestSource;
}

继承基类的类型一

package com.example.springboot.controller.model;

import lombok.*;

/**
 * @author tianmaolin004
 * @date 2023/8/14
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class JmBrandEnterSceneModel extends SceneModel {
    /**
     * 加盟品牌名称
     */
    private String brandName;
    /**
     * 加盟品牌ID
     */
    private String brandId;
    /**
     * 加盟公司税号
     */
    private String comTaxNo;

}

继承基类的类型二

package com.example.springboot.controller.model;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;

import java.time.LocalDateTime;

/**
 * @author tianmaolin004
 * @date 2023/8/14
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class JmsEnterSceneModel extends SceneModel {
 
    /**
     * 加盟商名称
     */
    private String franchiserName;
}

数据请求接口

请求接口

package com.example.springboot.controller;

import com.example.springboot.controller.model.SceneModel;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author tianmaolin004
 * @date 2023/8/14
 */
@RestController
@RequestMapping("/scene")
public class SceneSyncController {

    @PostMapping("/sync")
    public void sceneSync(@RequestBody SceneModel sceneModel) {
        System.out.println(sceneModel);
    }
}

请求实验示例

POSTMAN请求一

在这里插入图片描述

请求结果一

在这里插入图片描述

POSTMAN请求二
在这里插入图片描述
请求结果二

在这里插入图片描述

这样随着我请求的不同,Jackson依据不同请求Model中的属性进行解析判断。需要注意的是Jackson本身支持这一注解,并非只有SpringBoot支持,只不过SpringBoot的mvc请求使用了Jackson

JsonTypeInfo用法

这里简单普及一下,@JsonTypeInfo 是 Jackson 库中的注解之一,用于在序列化和反序列化 JSON 数据时处理多态性,特别是在处理继承结构时非常有用。它允许在 JSON 数据中包含有关对象类型的信息,以便正确地进行数据绑定。

以下是 @JsonTypeInfo 注解的主要参数和功能:

  • use:定义类型信息的使用方式。可以使用以下常量之一,以告诉 Jackson 库在序列化和反序列化时如何处理类型信息:

    • JsonTypeInfo.Id.CLASS:将类的全名作为类型信息。
    • JsonTypeInfo.Id.NAME:将一个字符串作为类型信息,需要与 @JsonSubTypes 注解一起使用,一般使用这个配置
    • JsonTypeInfo.Id.MINIMAL_CLASS:类似于 CLASS,但只使用类名的相对路径。
    • JsonTypeInfo.Id.NONE:不包含任何类型信息。
    • JsonTypeInfo.Id.CUSTOM:使用自定义的类型解析器处理类型信息。
  • include:定义类型信息的包含位置。可以是以下常量之一:

    • JsonTypeInfo.As.WRAPPER_OBJECT:将类型信息包装在 JSON 对象中。
    • JsonTypeInfo.As.PROPERTY:将类型信息作为 JSON 属性添加到数据中,一般使用这个配置
  • property:定义用于存储类型信息的属性名。默认为 "@class"。当 include 设置为 JsonTypeInfo.As.PROPERTY 时,此属性用于存储类型信息。

  • visible:设置类型信息是否可见。默认为 false,意味着类型信息不会序列化到 JSON 数据中。如果设置为 true,类型信息将包含在 JSON 数据中,一般使用这个配置设置为true

  • defaultImpl:定义默认的实现类,用于在反序列化时处理无法匹配类型信息的情况。

  • useDefaultImpl:设置是否在无法匹配类型信息时使用默认实现类。默认为 true

综上所述,@JsonTypeInfo 注解用于在序列化和反序列化 JSON 数据时处理多态性和继承结构,通过在数据中包含类型信息来确保正确的映射。

总结一下

JsonTypeInfo注解的使用可以降低同一类数据处理接口的提供数量,调用方可以只调用一个接口,接口内部可以依据调用方组装的Model和内置参数确定处理逻辑,扩展性和易用性都很强,在数据同步的场景里挺值得一用的。

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

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

相关文章

SQL进阶--SQL的常用技巧

一、ORDER BY FIELD() 自定义排序逻辑 排序 ORDER BY 除了可以用 ASC 和 DESC,还可以通过**ORDER BY FIELD(str,str1,...)**自定义字符串/数字来实现排序。这里用 order_diy 表举例,结构以及表数据展示: 二、CASE 表达式 「case when then el…

UI设计师个人工作感悟5篇

UI设计师个人工作感悟一 工作一年了,结合我自身谈谈UI设计的重要性。现在主流的论坛建站程序有两种 Phpwind 和Discuz(Phpwind被阿里巴巴收购 Discuz被腾讯收购这两个论坛程序都是开源免费的),利用这两种程序我都分别建立过论坛,我第一次用的…

7-15 然后是几点

有时候人们用四位数字表示一个时间,比如 1106 表示 11 点零 6 分。现在,你的程序要根据起始时间和流逝的时间计算出终止时间。 读入两个数字,第一个数字以这样的四位数字表示当前时间,第二个数字表示分钟数,计算当前时…

高效解决在pycharm环境下的UserWarning: loaded more than 1 DLL from .libs这类问题

文章目录 问题解决方案Plan APlan B 解决! 问题 这说明因同时存在多个动态链接库而存在冲突,所以需要删除其中一个 解决方案 Plan A Plan B 如果Plan A没用,就重装numpy,因为这个库就是numpy的 pip uninstall numpy pip insta…

zabbix-6.4 监控 MySQL

目录 1、rpm安装zabbix_agentd服务 2、编写zabbix_agentd.conf文件 3、编写模板文件 4、创建mysql用户并赋权限 5、创建.my.cnf文件 6、将规则添加到SELinux策略中 注意: 若模板无法读取.my.cnf 信息,从而导致监控报错,可以尝试修改模…

使用Python将文本转换为语音的简易应用

正文: 在本篇博客中,我们将介绍如何使用Python编写一个简单的应用程序,将文本转换为语音。我们将使用pyttsx3库进行文本到语音的转换,并通过pygame库来播放生成的语音。 C:\pythoncode\new\text2speech.py 首先,我们…

ReentrantReadWriteLock

关于读写锁状态的存取 // ReentrantReadWriteLock.Sync static final int SHARED_SHIFT 16; static final int SHARED_UNIT (1 << SHARED_SHIFT); static final int MAX_COUNT (1 << SHARED_SHIFT) - 1; static final int EXCLUSIVE_MASK (1 <&l…

小白到运维工程师自学之路 第七十三集 (kubernetes应用部署)

一、安装部署 1、以Deployment YAML方式创建Nginx服务 这个yaml文件在网上可以下载 cat nginx-deployment.yaml apiVersion: apps/v1 #apiVersion是当前配置格式的版本 kind: Deployment #kind是要创建的资源类型&#xff0c;这里是Deploymnet metadata: #metadata是该资源…

快手商品详情数据API 抓取快手商品价格、销量、库存、sku信息

快手商品详情数据API是用来获取快手商品详情页数据的接口&#xff0c;请求参数为商品ID&#xff0c;这是每个商品唯一性的标识。返回参数有商品标题、商品标题、商品简介、价格、掌柜昵称、库存、宝贝链接、宝贝图片、商品SKU等。 接口名称&#xff1a;item_get 公共参数 名…

JS实现树形结构、一维数组以及map之间的转换

const treeData[ {id:1, name:中国, children:[ {id:11,name:河南省,children:[{id:111,name:南阳市,children:[{id:1111,name:淅川县,children:null}]},{id:112,name:郑州市,children:[{id:1121,name:中牟县,children:null}]}] }, {id:22,name:广东省,children:[{id:221,name:…

【【verilog典型电路设计之流水线结构】】

verilog典型电路设计之流水线结构 下图是一个4位的乘法器结构&#xff0c;用verilog HDL 设计一个两级流水线加法器树4位乘法器 对于流水线结构 其实需要做的是在每级之间增加一个暂存的数据用来存储 我们得到的东西 我们一般来说会通过在每一级之间插入D触发器来保证数据的联…

创建Azure资源锁

锁的介绍 在Azure中&#xff0c;资源锁是一种用于保护订阅、资源组或者单个资源的机制。它可以防止对受锁定的资源进行删除或修改操作&#xff0c;帮助确保资源的连续可用性和安全性。 Azure中的资源锁可以分为两种类型&#xff1a; 删除锁&#xff08;CanNotDelete&#xf…

实现Excel数据复制分录信息粘贴到金蝶单据体中

>>>适合KIS云专业版V16.0|KIS云旗舰版V7.0|K/3 WISE 14.0等版本<<< 实现Excel数据复制分录信息粘贴到金蝶单据体分录中,在采购订单|采购入库单|销售订单|销售出库单等类型单据中,以少量的必要字段在excel表格中按模板填列好,很方便快捷地复制到金蝶单据表体…

三分钟完美解决你的C盘内存过大爆红

一、清理回收站 二、清理桌面 建议一 不要在桌面放太多图标或者文件会占用过多的内存,可以放到其他盘建议二、 将位置移动到别的盘 三、手动删除下载文件与缓存文件 日常使用中会通过Windows下载各种文件资料到电脑中&#xff0c;它默认也是直接下载在C盘中的。如果我们在以…

ssm+JSP的乡镇自来水收费系统源码和论文PPT

ssmJSP的乡镇自来水收费系统源码和论文PPT014 开发工具&#xff1a;idea 数据库mysql5.7(mysql5.7最佳) 数据库链接工具&#xff1a;navcat,小海豚等 开发技术&#xff1a;java ssm tomcat8.5 一、课题背景与意义 随着我国经济建设迅速发展&#xff0c;乡镇规模日益扩大&am…

RK3568 HDMI接口

一.简介 HDMI接口&#xff0c;中文全称为高清多媒体接口。是一种全数字化视频以及声音发送接口&#xff0c;能够发送没有压缩的音频以及视频信号。HDMI接口可以使用在机顶盒、DVD播放机等设备商。除此之外&#xff0c;HDMI接口还可以同时发送音频以及视频信号&#xff0c;简化…

22款美规奔驰GLS450更换AMG GLS63原厂刹车卡钳系统,刹车效果强悍无比

AMG出品的大六活塞卡钳及大直径开孔刹车碟&#xff0c;所组成的制动套件。这套AMG出品的卡钳为制动生产名厂BREMBO为其代工&#xff0c;刹车碟是高锻钢锻造&#xff0c;耐高温耐用性能较高且打孔设计。

什么是事务,并发带来的事务问题以及事务隔离级别(图文详解)

一、什么是事务&#xff1f; 简单说就是逻辑上的一组操作&#xff0c;要么都执行&#xff0c;要么都不执行。 举个例子&#xff0c;假如小明要给小红转账100元&#xff0c;这个转账会涉及到两个关键操作&#xff1a;①将小明的余额减少100元。 ②将小红的余额增加100元 。但…

【左神算法刷题班】第18节:汉诺塔问题、岛屿问题、最大路径和问题

第18节 题目1&#xff1a;汉诺塔问题&#xff08;变体&#xff09; 体系学习班18节有讲暴力递归的汉诺塔原题。 给定一个数组arr&#xff0c;长度为N&#xff0c;arr中的值只有1&#xff0c;2&#xff0c;3三种 arr[i] 1&#xff0c;代表汉诺塔问题中&#xff0c;从上往下第…

Azure添加网络接口

添加网络接口的意义 在 Azure 上&#xff0c;为虚拟机添加网络接口的意义包括以下几个方面&#xff1a; 扩展网络带宽&#xff1a;通过添加多个网络接口&#xff0c;可以增加虚拟机的网络带宽&#xff0c;提高网络传输速度和数据吞吐量。实现网络隔离&#xff1a;每个网络接口…