Gson实现接口自定义反序列化

Gson 优雅实现多个枚举的自定义(反)序列化过程 通过 Gson 优雅实现多个枚举的自定义(反)序列化过程 阅读详情

 

在项目中同样遇到了对json字符串进行反序列化时,遇到了多态情况下,无法找到对应类,所以写这篇文章来mark一下

首先抛出原始代码,再给上解决方案~

原始代码:

原始json串:

{"type":"int","specs":{"min":"1","max":"12","unit":"aw","unitName":"饱和度","step":"1"}}

TslDataType对象,Type 为内部枚举类,TslSpecs为接口,对应枚举类类型的各个实现类

TslDataType:构造方法中type是通过tslSpecs的方法来给赋值的

import com.lbs.iot.beans.tsl.specs.TslSpecs;

public class TslDataType {
    private final Type type;

    private final TslSpecs specs;

    public TslDataType(TslSpecs specs) {
        this.type = specs.getType();
        this.specs = specs;
    }

    public Type getType() {
        return type;
    }

    public TslSpecs getSpecs() {
        return specs;
    }

    public  enum Type {
        INT("int"),
        TEXT("text"),
        DATE("date"),
        BOOL("bool"),
        ENUM("enum"),
        ARRAY("array"),
        FLOAT("float"),
        STRUCT("struct"),
        DOUBLE("double");

        private final String type;

        Type(String type) {
            this.type = type;
        }

        public String getType() {
            return type;
        }


    }

}

 

TslSpecs接口:

import com.lbs.iot.beans.tsl.schema.TslDataType;

public interface TslSpecs {

    TslDataType.Type getType();

}

并附上两个实现类代码:IntSpecs和TexSpecs

import com.lbs.iot.beans.tsl.schema.TslDataType;

public class IntSpecs implements TslSpecs {

    private final int min;
    private final int max;
    private final int step;

    public IntSpecs(int min, int max, int step) {
        this.min = min;
        this.max = max;
        this.step = step;
    }

    public IntSpecs() {
        this(Integer.MIN_VALUE, Integer.MAX_VALUE, 1);
    }

    public int getMin() {
        return min;
    }

    public int getMax() {
        return max;
    }

    public int getStep() {
        return step;
    }

    @Override
    public TslDataType.Type getType() {
        return TslDataType.Type.INT;
    }
}
import com.lbs.iot.beans.tsl.schema.TslDataType;

public class TextSpecs implements TslSpecs {

    private final int length;

    public TextSpecs(int length) {
        this.length = length;
    }

    public TextSpecs() {
        this(2048);
    }

    public int getLength() {
        return length;
    }

    @Override
    public TslDataType.Type getType() {
        return TslDataType.Type.TEXT;
    }
}

这种情况下,直接通过Gson的构建对象来反序列化是无法成功的,

会报错Unable to invoke no-args constructor for interface com.lbs.iot.beans.tsl.specs.TslSpecs,Registering an InstanceCreator with Gson for this type may fix this problem.

原因:这是因为反序列化的时候,遇到了TslSpecs接口,无法确定是那个实现类,所以无法实例化,所以才出现了上面的问题,

那么解决的办法就是,自定义反序列化,遇到此接口时能找到对应的实现类。

解决办法:

第一步,自定义TslDeserializer 类实现 JsonDeserializer<TslDataType>接口,并传入对象泛型。类里包含了构造方法,自定义注册方法,自定义反序列化处理方法

在deserialize方法中就能获取到对象对应的json块,然后根据json串中的type值就可以获取到提前注册到map中的对应的实现类(第二步构建Gson的时候会明白);

import com.google.gson.*;
import com.lbs.iot.beans.tsl.schema.TslDataType;
import com.lbs.iot.beans.tsl.specs.TslSpecs;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

public class TslDeserializer implements JsonDeserializer<TslDataType>
{
  String tslTypeElementName;
  Gson gson;
  Map<String, Class<? extends TslSpecs>> tslTypeRegistry;

  public TslDeserializer(String tslTypeElementName)
  {
    this.tslTypeElementName = tslTypeElementName;
    gson = new Gson();
    tslTypeRegistry = new HashMap<>(); // Java 7 required for this syntax.
  }

  public void registerSpecsType(String tslTypeName, Class<? extends TslSpecs> tslSpecs)
  {
    tslTypeRegistry.put(tslTypeName, tslSpecs);
  }

  @Override
  public TslDataType deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException
  {
    JsonObject tslDataObject = json.getAsJsonObject();
    JsonElement tslTypeElement = tslDataObject.get(tslTypeElementName);
    Class<? extends TslSpecs> tslSpecs = tslTypeRegistry.get(tslTypeElement.getAsString());
    TslSpecs specs = gson.fromJson(tslDataObject.get("specs"), tslSpecs);
    TslDataType dataType = new TslDataType(specs);
    return dataType;
  }
}

第二步,根据自定义TslDeserializer类,来构建Gson对象,

此处需要注意:原始json串中的type值是关键,反序列化时是根据type值来与 tslDeserializer.registerSpecsType中的key来对应的,所以进行接口反序列化的时候,必定要有一个通用的key来进行区分,否则无法进行实现类的对应匹配,也就无法完成实例化

TslDeserializer tslDeserializer = new TslDeserializer("type");此行代码就是指定了根据Json串中那个字段来获取key,然后通过key值从自定义注册器中获取对应的class类进行实例化,然后再通过gosn的反序列化,即可实例化对象,然后返回对象即可~

//先创建对象,再根据type值进行注册,并映射对应的实现类
TslDeserializer tslDeserializer = new TslDeserializer("type");
        tslDeserializer.registerSpecsType("int", IntSpecs.class);
        tslDeserializer.registerSpecsType("text", TextSpecs.class);
        tslDeserializer.registerSpecsType("date", DateSpecs.class);
        tslDeserializer.registerSpecsType("bool", BoolSpecs.class);
        tslDeserializer.registerSpecsType("enum", EnumSpecs.class);
        tslDeserializer.registerSpecsType("array", ArraySpecs.class);
        tslDeserializer.registerSpecsType("float", FloatSpecs.class);
        tslDeserializer.registerSpecsType("struct", StructSpecs.class);
        tslDeserializer.registerSpecsType("double", DoubleSpecs.class);

//将tslDeserializer注册进TypeAdapter中去,遇到TslDataType.class时,就走自定义方法中
        Gson gson = new GsonBuilder()
                .serializeNulls()
                .registerTypeAdapter(TslDataType.class, tslDeserializer)
                .create();

第三步:直接 通过上面获取到的gosn对象,进行反序列化获取对象即可

TslDataType tslDataType = gson.fromJson(jsonData, TslDataType.class);

至此,基于Gson的接口反序列化也实现了。

此处重点是,所有的实现类都需要有一个相同的字段来进行标识区分。此json串中 type就担任此职能,一定要注意这一点~~~~!!!

Gson处理复杂对象、反序列化丢失精度、接口无法实例化、多态解决方案 该文章只适用于刚接触Gson的小白看,该篇文章也是大概讲解其调用流程,这样便于我们后续更好的适用Gson。 Gson 是内置处理复杂序列化对象的,一般搜索到到处理多态的方案为: 自定义TypeAdpater -适用于各种复杂的类,但需自定义 使用泛型 -无法适用于第三方的类 RuntimeTypeAdapterFactory -只适用于较为简单的多态类的情况 举例: 在使用普通的Gson gs... 阅读详情

相关推荐

Android 中使用Gson完成对象的序列化与反序列化

前言: JSON(JavaScript ObjectNotation):是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。 Gson简介:Gson是Google提供的用来在java对象和json数据之间进行映射的java类库,可以将一个JSON字符串转成一个java对象(反序列化),或者将java对象转成一个JSON字符串(序列化)。 在Android 下build.gradle下引入依赖: 接下来用一个使用Gson将Student类型对象进行序列化,与反序列 1.Student类

路宇的博客 2417

Gson解析(序列化,反序列化)

Gson解析(序列化,反序列化) Gson 是google解析Json的一个开源框架,是Google提供的用来在java对象和JSON字符串之间进行映射的类库,可以将一个JSON字符串转成一个java对象(反序列化),或者把java对象转成一个JSON字符串(序列化) 1.导入依赖 implementation 'com.google.code.gson:gson:2.8.6' 2.Gson的基本用法之JavaBean转换成Json字符串 gson提供 publicString toJson(Obje

twenty_four_7的博客 3926

AI视频生成技术研究报告:现状、挑战与展望

AI 视频生成技术概述:介绍 AI 视频生成技术的基本概念,回顾其发展历程,从早期依赖图像拼接的简单生成方式,到如今融合多种先进技术的复杂模型应用,梳理技术演进的关键节点和重要突破。同时,分析该技术在当前阶段的特点,包括生成视频的质量、速度、灵活性等方面,以及与传统视频制作方式的差异,阐述 AI 视频生成技术如何改变视频创作的流程和模式。技术实现路径分析。

daqsdfas的博客 4574

gson自定义反序列化器

写在前面 gson提供了一套强大的序列化、反序列化器。但某些场景下,如反序列化父子类时,gson现成反序列化器只能识别到父类的属性信息,子类属性会丢失。 普通的反序列化器是不能用的。需要自定义反序列化器,强加自己的业务逻辑。不是闲着蛋疼去实现自定义的序列化器。 举个栗子 school对象 public class School { private String name; pri

csdn_xpw的博客 3151

(MATLAB)一维信号峰值检测findpeaks

一维信号波峰波谷检测,峰值、峰宽、到达时间计算。MATLAB自带的findpeaks函数能完成这一任务,在这里分享其基本用法与特殊用法。

HPC_ZY 2万+

PaddleOCR GPU部署:从环境配置到避坑实战指南

本文详细介绍了PaddleOCR GPU部署的全过程,从环境配置到避坑实战指南。通过分析常见的部署失败原因,提供硬件兼容性自查、软件环境精配方案以及路径配置的解决方案,帮助用户高效完成GPU加速的OCR任务部署,避免90%的常见错误。

weixin_30839881的博客 417

Gson反序列化Deserializer详解

Gson JsonDeserializer

菜鸟博客 1万+

解决UE5像素流三大痛点:鼠标锁定/双光标/自动播放(附app.js魔改指南)

本文针对UE5像素流服务在实际应用中常见的鼠标锁定、双光标和自动播放三大交互痛点,提供了深入的技术分析和解决方案。通过详细解析app.js源码,指导开发者如何修改控制方案、修复光标显示以及实现静音自动播放,旨在提升Pixel Streaming应用的用户体验与专业度。

weixin_28025327的博客 381

Gson 反序列化

本文延续前一篇文章,继续介绍简单基本的Gson用法。这篇文章我们将介绍如何将复杂的JSON对象解析为Java对象,其中Java对象的结构可以与JSON对象不一致。我们还会看到如何使用Gson反序列化器(JsonDeserializer Java文档)将JSON对象映射为Java对象。观察 请注意,文中解析(parse)与反序列化(deserialise)将互换使用。 下面列出的所有代码都可以在

请叫我搞向 2201

统信UOS服务器上,达梦DM8数据库安装避坑全记录(附大小写敏感设置)

本文详细介绍了在统信UOS服务器版上部署达梦DM8数据库的全过程,包括环境准备、安装流程、数据库实例初始化及关键参数配置,特别是大小写敏感设置的注意事项。提供了从系统配置到性能优化的完整指南,帮助用户避免常见问题,确保数据库稳定运行。

weixin_30647423的博客 331

uniapp串口通信实战:从零搭建物联网设备控制App(附完整代码)

本文详细介绍了如何使用Uniapp实现串口通信,从零搭建物联网设备控制App。内容涵盖环境配置、串口初始化、数据收发、错误处理等核心功能,并提供了完整的代码示例,帮助开发者快速掌握跨平台串口通信技术,适用于智能农业、工业自动化等物联网场景。

weixin_30369041的博客 597

Gson实现枚举自定义反序列化

项目中前后端交互使用json,遇到复杂结构对象(比如:对象,多态,枚举等等)json串,进行反序列化时,可能无法得到我们想要的结果,此时就需要做一些处理了。下面直接上代码演示吧 枚举类: 自定义json串: {"dataType":{"type":"int"}} 这里只取复杂对象中的某一个相关类,定义了一个TslDataTypeRR类,枚举类Type为内部类,此时是最开始对象,反序列化的时候,是无法拿到Type属性值的 public class TslDataTypeRR { priv

TOP__ONE的博客 1400

提高RFID检测距离以及检测速度的方法总结

摘要:提高RFID检测距离需优化阅读器功率、标签灵敏度、天线设计及频段选择,同时减少环境干扰;提升检测速度则需改进防碰撞算法、增强并行处理能力、精简数据传输。实际应用需平衡两者关系,如物流仓储采用UHF频段、高增益天线和动态Q算法实现远距离高速读取,ETC系统则通过微波频段和高速调制实现超远距离快速识别。不同场景需针对性优化硬件配置和系统参数。

start_up_go的博客 292

Gson自定义序列化与反序列化

前言 在使用Gson的时候我们经常需要根据自己的需求定义序列化和反序列化的规则,本文主要讲解如何优雅地进行Gson的序列化和反序列化。 序列化 方法 实现JsonSerializer接口 注册自定义的序列化实现 demo 自定义UserInformationBeanSerializer并实现JsonSerializer接口 public class User...

ai-exception的博客 4859

AUTOSAR TcpIp模块 以太网配置开发2

someip协议之tcpIp协议

汽车电子电气 1085

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Gson 使用篇

Gson 使用篇 开篇:在使用Gson之前,我们先聊一下Json, 虽然大部分人都用过,经常用,但有时候并不会太注意细节,写这篇博客也是为了更清晰的了解Gson是如何解析Json,这篇博客主要讲解Json的语法,以及使用Gson如何解析Json,下篇博客讲解Gson解析Json的主要流程及原理,网上很多类似的博客,这里也算自己学习的一个记录,总结。 一. Json 是什么? Json 是诸多序列化方案的一种,是一种轻量级的数据交换格式,主要用于数据的网络传输,本地存储,数据标记使用。 二. Json 语法格

优快云NETVIP的博客 918

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Retrofit实战之json反序列化的那些事

Retrofit实战之json反序列化的那些事retrofit是一个十分优秀的网络框架,它为了我们封装了很多内容,使我们请求十分方便,获取也十分轻松,对于返回的json可以轻松的用gson自动解析。但是在这个方便的后面,也带来了一些小小的隐患。下面就有两种情况,在json被反序列化时,给我们在这个炎热的夏天里造成了蛋蛋的凉意。接口请求失败,可它还是要全部反序列化一般来说接口返回的形式包括:返回码,信

kyosky110的专栏 4542

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Gson源码解析

Gson简介 Gson,就是帮助我们完成序列化和反序列化的工作的一个库。 日常用法 UserInfo userInfo = getUserInfo(); Gson gson = new Gson(); String jsonStr = gson.toJson(userInfo); // 序列化 UserInfo user = gson.fromJson(jsonStr,UserInfo.class); .

961

Gson反序列化中的NULL值替换(各种类型)

相信很多移动开发在后台开发接口时,曾一遍遍的发生过如下场景~ 移动端: 不要传null!不要传null!不要传null! 后台: 放心吧,大兄弟,我怎么会传null给你呢(滑稽脸) 结果在对接口时才发现,曾经的誓言都喂了狗,这些null就像垃圾短信一样,时不时的蹦出来骚扰你,轻则影响UI展示,重则导致应用崩溃。于是你怒气冲冲的跑去质问后台,发生如下场景。。 移动端: 为什么要骗我?说...

Ever69的博客 7049

GSON速学必会

一. GSON 简介 GSON是一个Java语言编写的用于处理JSON数据格式的开源应用程序编程接口项目。它将Java对象转换为JSON表示。还可以用于将JSON字符串转换为等效的Java对象。 gson包包含了JSON数据处理的所有常见类和接口。gson内部的子包reflect,annotation, 和stream。reflect包包含处理Java泛型类型信息的类和接口。...

aitong0065的博客 150

Gson @JsonAdapter实现对json指定属性进行加密

在项目开发中,对于一些敏感属性,可能需要进行加密处理。比如下面的对象中的name若需要加密。可在name上加上@JsonAdapter注解。 /** * JsonAdapter * 用来自定义序列化 和 反序列化 * * 这种形式比较单一 , * 序列化 : 放置在 该类的属性上 * 反序列化时: 实现 JsonDeserializer<该类名> * ...

1962

GSON解析工具类碰到byte[]类型报错JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but

GSON解析工具类碰到byte[]类型报错 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 102 path $.lpdata 开发项目中碰到的,其中使用GsonUtils工具类直接解析我要的实体,但是出现了报错。看了其他的文章说是我的数据类型内容不对,但是我的存储输入跟输出其中并没有什么问题,新增的实体中lpd

qq_28846883的博客 1097

Gson 对enum的序列化与反序列化配置

Gson 对enum的序列化与反序列化配置 前言 在网上找了一圈,都没有一个能够直接配置使用的Gson序列化enum配置。 对于enum序列化与反序列化的主要难点在于TypeAdapter在反序列化时无法获取enum的类型,此处提供的解决方案可以通过闭包的方式从TypeAdapterFactory实例中获取enum的class,在此放出一份最简单的增强Gson序列化与反序列化enum的方法。 (可选则将enum序列化为enum序号或名字,也可选通过enum的序号或名字或两者反序列化enum) /** *

PDragon_s的博客 2055

Gson将字符串转换为Date类型

自定义DateAdapter public class DateAdapter implements JsonDeserializer<Date> { private final DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); public Date deserialize(JsonElement arg0...

aijia4259的博客 1100

gson自定义枚举类型序列化反序列化

基于gson,自定义枚举类型序列化反序列化,实际效果如下: 实体类:OrderDO:{orderNo="202109050001",status=StatusEnum.PENDING}<-->json串:{"orderNo":"202109050001","status":{"value":2,"desc":"处理中"}} 需求背景:将枚举元素序列化为带有值和说明(value/desc)的json串(json接收方就不需要自己翻译了),反序列化则基于值(value)进行匹配 问题:由于...

wb_snail的博客 2503
上一篇: Gson实现枚举自定义反序列化
下一篇: 设计模式之单例模式
TOP__ONE
博客等级 码龄10年 74粉丝 117原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值