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

这篇具有很好参考价值的文章主要介绍了SpringBoot -- 请求数据多态映射(jackson)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

实现方式

可以通过 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"
    }
]
接参结果

SpringBoot -- 请求数据多态映射(jackson),spring boot,后端,java

@JsonTypeInfo 和 @JsonSubTypes

以上的方式我们是通过根据对象中的某个属性,判断反序列化时应该反序列化为那种类型的对象,如果不配置 property 字段,默认读取 json 对象中的 @type 属性
SpringBoot -- 请求数据多态映射(jackson),spring boot,后端,java

其他常用映射方式
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"
}

SpringBoot -- 请求数据多态映射(jackson),spring boot,后端,java

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"
    }
]

SpringBoot -- 请求数据多态映射(jackson),spring boot,后端,java文章来源地址https://www.toymoban.com/news/detail-734897.html

到了这里,关于SpringBoot -- 请求数据多态映射(jackson)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Jackson 2.x 系列【25】Spring Boot 集成之起步依赖、自动配置

    有道无术,术尚可求,有术无道,止于术。 本系列Jackson 版本 2.17.0 本系列Spring Boot 版本 3.2.4 源码地址:https://gitee.com/pearl-organization/study-jaskson-demo Spring Boot 是当前最流行的 Java 应用开发框架,简化开发的同时也导致了很多开发人员只会写业务代码,并不太清楚内部组件和配

    2024年04月17日
    浏览(43)
  • 【Spring Boot 使用Filter统一处理请求数据转换】

    Spring Boot Filter 使用场景 身份验证和授权 场景描述: 在用户访问应用程序的敏感资源之前,需要验证用户的身份并授权用户访问特定的内容。 实现方式: 使用Filter拦截请求,检查HTTP请求中的身份验证令牌(如JWT),并确定用户是否具有执行操作的权限。 日志记录和审计 场景

    2024年02月21日
    浏览(43)
  • Springboot后端通过路径映射获取本机图片资源

    项目场景: 项目中对图片的处理与查看是必不可少的,本文将讲解如何通过项目路径来获取到本机电脑的图片资源 如图所示,在我的本机D盘的图片测试文件夹(文件夹名字不要有中文)下有一些图片, 我们要在浏览器上访问到这些图片,很简单,只需要在浏览器导航栏中填写

    2024年02月14日
    浏览(31)
  • Spring Boot静态资源映射

    在 Web 应用中会涉及到大量的静态资源,例如 JS、CSS 和 HTML 等。我们知道,Spring MVC 导入静态资源文件时,需要配置静态资源的映射;但在 SpringBoot 中则不再需要进行此项配置,因为 SpringBoot 已经默认完成了这一工作。 Spring Boot 默认为我们提供了 3 种静态资源映射规则: We

    2023年04月24日
    浏览(39)
  • 后端使用Spring Boot生成Excel文件,前端使用微信小程序上送数据并下载Excel文件

    后端:Spring Boot生成Excel文件添加依赖 在 pom.xml 中添加Apache POI的依赖: 创建一个用于生成Excel文件的方法         4.创建一个用于处理Excel文件的Controller 前端:微信小程序上送数据并下载Excel文件 在 app.json 中添加一个用于下载Excel文件的页面: 在 pages/download 目录下创建

    2024年04月11日
    浏览(88)
  • Java后端返回的MySQL日期数据在前端格式错误的解决方法,区分jackson和fastjson

    在写web项目的时候经常会遇到后端返回的MySQL 日期数据(date) 类型在前端显示不正确的情况,有的时候会出现一串数字的时间戳,有的时候显示为日期晚了一天。 这是因Json给前端返回数据的时候格式问题造成的 其实总结起来就是一句话在Model部分对于JavaBean定义参数类型的时

    2024年02月03日
    浏览(43)
  • 从零开始 Spring Boot 63:Hibernate 继承映射

    图源:简书 (jianshu.com) 关系型数据库设计中是不存在继承概念的,但实体类可以用继承来组织代码结构,所以需要用一种方式将实体类的继承结构映射到表结构。 本文将介绍几种在 JPA(Hibernate)中映射实体类继承层次的方式。 第一种方式是用 @MappedSuperclass 标记超类(Super

    2024年02月12日
    浏览(49)
  • 【Spring Boot】SpringBoot和数据库交互: 使用Spring Data JPA

    在现代应用程序的开发中,数据是核心部分。为了能够持久化、检索、更新和删除数据,应用程序需要与数据库进行交互。 1.1 为什么需要数据库交互 数据持久化 :当你关闭应用程序或者服务器时,你仍希望数据能够保存。数据库提供了一个持久的存储方案,使得数据在关闭

    2024年02月12日
    浏览(50)
  • Spring Boot 整合 Shiro(后端)

    1 Shiro 什么是 Shiro 官网: http://shiro.apache.org/ 是一款主流的 Java 安全框架,不依赖任何容器,可以运行在 Java SE 和 Java EE 项目中,它的主要作用是对访问系统的用户进行身份认证、 授权、会话管理、加密等操作。 Shiro 就是用来解决安全管理的系统化框架。 2 Shiro 核心组件 用

    2024年02月09日
    浏览(49)
  • 前端处理后端传来的Long型数据精度丢失的问题--对象转换器Jackson0bjectMapper

    1、问题描述 前端提交参数 后端处理 前端js对long型数据进行处理时丢失精度(只能保证16位),导致提交的id和数据库中的id不一致。 2、 问题实现 如何解决这个问题? 我们可以在服务端给页面响应json数据时进行处理,将long型数据统一转为String字符串 3、具体代码实现–对象

    2024年02月16日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包