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

Gson枚举序列化实现 众所周知,Json是无法传递枚举类型的,在对Json处理的过程中,可能大家或多或少都会遇到对于枚举处理的问题,当然解决方式也有很多种,本篇仅针对使用Gson处理Json时对于枚举问题给出一种解决方式,可能并不能适用于小伙伴们实际应用的所有场景,但作为借鉴也算是一个不错的选择。 阅读详情

项目中前后端交互使用json,遇到复杂结构对象(比如:对象,多态,枚举等等)json串,进行反序列化时,可能无法得到我们想要的结果,此时就需要做一些处理了。下面直接上代码演示吧

枚举类:

自定义json串:

{"dataType":{"type":"int"}}

这里只取复杂对象中的某一个相关类,定义了一个TslDataTypeRR类,枚举类Type为内部类,此时是最开始对象,反序列化的时候,是无法拿到Type属性值的

public class TslDataTypeRR {
    private final Type type;
    public TslDataTypeRR(Type type) {
        this.type = type;
    }
    public Type getType() {
        return type;
    }
   
    public enum Type  {
        INT("int"),
        TEXT("text");

        private final String type;
        Type(String type) {
            this.type = type;
        }
        public static Type getItem(String type){
            for(Type item : values()){
                if(item.getType().equals(type)){
                    return item;
                }
            }
            return null;
        }

        public String getType() {
            return type;
        }
      
    }

通过Gson反序列化是无法拿到期望结果的

Gson gson = new GsonBuilder()
                .serializeNulls()
               .create();
TslDataTypeRR element2 = gson.fromJson(jsonData, TslDataTypeRR.class);

下面进行解决方案演示:

第一步,定义一个接口

public interface GsonEnum<E> {
 
    String serialize();
 
    E deserialize(String jsonEnum);
 
}

第二步,构建一个Adapter: GsonEnumTypeAdapter,来根据GsonEnum来处理此类枚举接口,方便以后其他枚举类,直接套用此方法

import com.google.gson.*;

import java.lang.reflect.Type;

public class GsonEnumTypeAdapter<E> implements JsonSerializer<E>, JsonDeserializer<E> {
 
    private final GsonEnum<E> gsonEnum;
 
    public GsonEnumTypeAdapter(GsonEnum<E> gsonEnum) {
        this.gsonEnum = gsonEnum;
    }
 
    @Override
    public JsonElement serialize(E src, Type typeOfSrc, JsonSerializationContext context) {
        if (null != src && src instanceof GsonEnum) {
            return new JsonPrimitive(((GsonEnum) src).serialize());
        }
        return null;
    }
 
    @Override
    public E deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if (null != json) {
            return gsonEnum.deserialize(json.getAsString());
        }
        return null;
    }
 
}

第三步,需要实现枚举自定义序列化的枚举类,实现上方GsonEnum接口并将枚举类型当泛型传进去,并重写序列化和反序列化方法,写parse方法来辅助

public class TslDataTypeRR {

    private final Type type;
    public TslDataTypeRR(Type type) {
        this.type = type;
    }

    public Type getType() {
        return type;
    }

    public static enum Type implements GsonEnum<TslDataTypeRR.Type> {
        INT("int"),
        TEXT("text"),
        DOUBLE("double");

        private final String type;

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

        public static Type getItem(String type){
            for(Type item : values()){
                if(item.getType().equals(type)){
                    return item;
                }
            }
            return null;
        }


        public String getType() {
            return type;
        }

        //此方法里面,有几个枚举值,就写几个case
        public static Type parse(String faction) {
            switch (faction) {
                case "int":
                    return Type.INT;
                case "text":
                    return Type.TEXT;
                case "double":
                    return Type.DOUBLE;
                default:
                    throw new IllegalArgumentException("There is not enum names with [" + faction + "] of type Faction exists! ");
            }
        }


        @Override
        public String serialize() {
            return this.getType();
        }

        @Override
        public Type deserialize(String jsonEnum) {
            return Type.parse(jsonEnum);
        }
    }

第四步,构建Gson对象,将自定义序列化adapter加入初始化中,并

 Gson gson = new GsonBuilder()
                .serializeNulls()
//此处只是传了一个TslDataType.Type.TEXT,只是为了获取此枚举类,写任意一个枚举类值都可以
//如果还有其他的枚举类需要反序列化,只需让枚举类重复第三步,并在此多加一条registerTypeAdapter即可
                .registerTypeAdapter(TslDataTypeRR.Type.class, new GsonEnumTypeAdapter<>(TslDataType.Type.TEXT)) 
                .create();

TslDataTypeRR element2 = gson.fromJson(jsonData, TslDataTypeRR.class);
//fixme 此时,这element2中的type就通过 int值反序列化成 INT枚举类型了

注:

  • 此处只是传了一个TslDataType.Type.TEXT,只是为了获取此枚举类,写任意一个枚举类值都可以
  • 如果还有其他的枚举类需要反序列化,只需让枚举类重复第三步,并在此多加一条registerTypeAdapter即可

至此,就完成了基于Gson的枚举自定义反序列化

 

第二种方法,直接lmd实现Gson的自定义序列化和反序列化,直接附上工具代码吧,看一眼应该就能明白

 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);
        Gson gson = new GsonBuilder()
                .serializeNulls()
                .registerTypeAdapter(TslDataType.class, tslDeserializer)
                .registerTypeAdapter(TslDataType.Type.class, (JsonSerializer<TslDataType.Type>) (src, typeOfSrc, context) -> context.serialize(src.getType()))
                .registerTypeAdapter(TslServiceElement.CallType.class, (JsonSerializer<TslServiceElement.CallType>) (src, typeOfSrc, context) -> context.serialize(src.getType()))
                .registerTypeAdapter(TslEventElement.EventType.class, (JsonSerializer<TslEventElement.EventType>) (src, typeOfSrc, context) -> context.serialize(src.getValue()))
                .registerTypeAdapter(TslServiceElement.CallType.class,(JsonDeserializer<TslServiceElement.CallType>)(json,typeOf,context) -> TslServiceElement.CallType.getItem(json.getAsString()))
                .registerTypeAdapter(TslEventElement.EventType.class,(JsonDeserializer<TslEventElement.EventType>)(json,typeOf,context) -> TslEventElement.EventType.getItem(json.getAsString()))
                .setPrettyPrinting()
                .create();

 

 

Gson解析(6)——注册TypeAdapter及处理Enum类型 / 这个 state是枚举值。// json转为对象时调用,实现JsonDeserializer接口。// 对象转为Json时调用,实现JsonSerializer接口。 阅读详情

相关推荐

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

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

RekaDowney的博客 8341

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

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

wb_snail的博客 2503

Gson系列5 --- 总结篇 -- TypeAdapter JsonSerializer 与 JsonDeserializer @JsonAdapter

# TypeAdapter JsonSerializer 与 JsonDeserializer @JsonAdapter 类的序列化与反序列化 @SEE @JsonAdapter篇 和 序列化null值 方式1: JsonSerializer 与 JsonDeserializer 可以 自动的与 @JsonAdapter 使用 方式2: 也可以手动注册...

sunrainamazing的博客 4744

使用Gson对多个枚举类型的统一序列化/反序列化处理

关于源码,已经迁移到GitHub上,地址https://github.com/google/gson 也可以直接在这个地址下载,已集成下面文章中的方法 -------------------------------------------------------------------------------------以下正文 看文章前请先下载最新Gson代码,地址: https://

atm008的专栏 4521

Gson 枚举类型的统一序列化/反序列化处理

实现了通过gson对enum的自定义转化过程,不需要预先定义enmu,并且不需要修改gson源码,在框架顶层处理基本可以达到对enum的抽象管理。

Outlook邮件备份全攻略:从导出到导入的完整流程(附常见问题解决)

本文提供了一份详尽的Outlook邮件备份全攻略,涵盖从导出到导入的完整流程。重点解析了经典桌面版Outlook的.pst文件备份方法、进阶的智能筛选备份策略,以及如何通过导入恢复和工具验证确保备份可用。同时,文章还介绍了构建自动化备份体系与异地容灾的最佳实践,并附有常见问题解决方案,帮助用户建立可靠的邮件数据安全防线。

weixin_29248611的博客 891

Json转换利器Gson之实例六-注册TypeAdapter及处理Enum类型

枚举类型给我们的程序带来了好处,如何用Gson来实现与Json的互转呢?请看本文. 本文重点掌握如何自己写一个TypeAdapter及注册TypeAdapter和处理Enum类型. 实体类: [java] view plaincopy public enum PackageState {       PLAY, UPDATE, UP

992

ChatGPT Plus完整开通指南:从账号注册到稳定使用全流程

自然语言处理(NLP)技术通过深度学习模型实现对人类语言的理解与生成,其核心原理是基于Transformer架构的大规模预训练。GPT-4作为当前最先进的生成式AI模型,在代码编写、文档分析等场景展现出显著的技术价值。在实际应用中,稳定的网络环境和合规的支付方式是确保AI助手持续服务的关键因素。针对ChatGPT Plus的开通,需要系统性地解决账号验证、虚拟信用卡支付等工程实践问题,才能实现工作流的高效整合。

weixin_34239592的博客 428

Java枚举类型通过Gson序列化与反序列化

enum ApiResultStatus { /** * 成功 */ SUCCESS(200), /** * 失败 */ FAILED(400), /** * 未定义 */ UNDEFINED(0); public int status; ApiResultStatus(int status) { this.status = status; }

qq_19266669的博客 1377

别再硬编码了!WinCC子画面动态加载的5种C脚本写法对比

本文深入解析WinCC子画面动态加载的5种C脚本实现方案,包括基础加载、路径动态解析、多语言切换、窗口自适应布局和混合架构交互。通过代码示例和场景分析,帮助开发者避免硬编码问题,提升工业自动化系统的交互效率和可维护性。特别推荐路径动态解析方案,有效解决项目路径管理的痛点。

weixin_29008691的博客 476

基于Android13的系统启动流程分析(三)之FirstStageMain阶段

init进程是Android系统中用户空间的第一个进程,作为第一个进程,它被赋予了很多极其重要的工作职责,比如创建zygote(孵化器)和属性服务等。init进程是由多个源文件共同组成的,这些文件位于源码目录system/core/init1. Bootloader 引导当按下设备电源键时,最先运行的就是 bootloader(固化在ROM的程序),bootloader 的主要作用就是硬件设备(如 CPU、flash、内存)的初始化并加载到RAM,通过建立内存空间映射,为装载 Linux 内核做好准备,。

q1210249579的博客 5496

Gson TypeAdapter用法

Gson TypeAdapter用法 实例:写一个TypeAdapter,注册TypeAdapter来处理Enum类型.   实体类: public enum Color { RED("红色",1),GREEN("绿色",2),BLANK("白色",3), YELLO("黄色", 4); private String name; private int index; ...

qi_ling的博客 349

软件需求规格说明书(SRS)标准模板

《软件需求规格说明书(SRS)框架解析》摘要: 本文档系统阐述了SRS的标准结构,包含7大核心部分:1)引言(目的、背景和术语);2)总体描述(产品定位与用户特征);3)功能需求(模块化功能说明);4)非功能需求(性能、安全等指标);5)接口需求(用户/硬件/软件接口);6)其他技术要求;7)附录(图表与参考资料)。重点突出了功能需求模块的标准化描述模板(FR-01),以及安全需求中的HTTPS通信、SHA-256加密等关键指标。该框架为软件开发提供了明确的需求基准,涵盖从业务背景到技术实现的完整链条,是确

moton2017的博客 2890

告别枚举序列化痛点:Gson EnumTypeAdapter与SerializedName注解实战指南

你是否还在为Java枚举(Enum)的JSON序列化/反序列化问题头疼?当API接口返回的枚举值与代码定义不一致时,当数据库存储的枚举字符串需要映射到不同的Java枚举常量时,手动编写转换逻辑不仅繁琐易错,还会让代码变得臃肿不堪。本文将带你彻底解决这些问题,通过Gson框架的EnumTypeAdapter和SerializedName注解,实现枚举类型与JSON数据的无缝转换,让你从此告别枚举处理

gitblog_00538的博客 451

手把手教你学AUTOSAR(13.1)--基于 AUTOSAR 的开发实战实例(一)

通过上述几个基于 AUTOSAR 的开发实战实例,你可以全面了解如何从需求分析、系统设计、软件开发、集成测试到部署和验证等多个环节进行 AUTOSAR 系统的开发。这些实例不仅涵盖了不同的应用场景,还提供了具体的代码实现和技术细节,帮助你更好地应用 AUTOSAR 标准。

MHD0815的博客 1195

【StreamSet】ETL之StreamSet之Pipelines的状态监听之WebHook钉钉篇

介绍下StreamSets的状态监听以及钉钉的webhook的互联,这位博友问的恰是时候,不久前我刚刚对接过钉钉的机器人,这次看到这个问题,对我来说,应该轻车熟路了,那就有了这篇博文,状态监听之钉钉篇。...

m0_54252387的博客 488

利用gson解析和生成json数据(二)

包含枚举类型的对象转换成json字符串

mockingbirds的专栏 951

搞定ESD(五):静电放电问题分析与调试

前面深入分析了静电放电的干扰机理、耦合路径,从现在开始将进入下一个大家非常关注的环节:静电放电问题分析与调试,掌握静电放电问题的分析方法,快速锁定敏感设备或者耦合路径,可以达到事半功倍的效果。

记得诚 2795

GsonBilder注册TypeAdapter及处理Enum类型

枚举类型给我们的程序带来了好处,如何用Gson来实现与Json的互转呢?请看本文. 本文重点掌握如何自己写一个TypeAdapter及注册TypeAdapter和处理Enum类型. 实体类: [java] view plaincopy public enum PackageState {       PLAY, UPDATE, UP

Caesardadi的专栏 2487

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

上一篇: Zookeeper之linux系统下安装教程
下一篇: Gson实现接口自定义反序列化
TOP__ONE
博客等级 码龄10年 74粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值