• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

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

武飞扬头像
存在morning
帮助1

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

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhhaehib
系列文章
更多 icon
同类精品
更多 icon
继续加载