首页 前端知识 【工作中问题解决实践 九】使用@JsonTypeInfo实现请求数据对象多态

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

2024-06-14 23:06:46 前端知识 前端哥 567 363 我要收藏

最近在处理接口请求进行数据写入的一个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和内置参数确定处理逻辑,扩展性和易用性都很强,在数据同步的场景里挺值得一用的。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/12177.html
标签
spring
评论
发布的文章

fastjson升级为fastjson2

2024-06-20 09:06:18

protobuf对象与JSON相互转换

2024-06-20 09:06:14

NVM 及 PNPM 安装

2024-06-20 09:06:01

npm有哪些插件包??

2024-06-20 09:06:01

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!