带有GSON和抽象类的JSON

经过多年使用org.json库在Java中支持JSON数据交换格式后,我已切换到Google Gson 。 org.json是一个较低级的库,因此您必须创建JSONObject,JSONArray,JSONString等…并执行其他低级工作。 Gson简化了这项工作。 它提供了简单的toJson()和fromJson()方法,可将任意Java对象转换为JSON,反之亦然,支持Java泛型,允许对象的自定义表示,生成紧凑且可读性强的JSON输出,并具有许多其他优点。 我越来越喜欢它。 使用很简单。 假设我们有一个叫做Circle的类。
public class Circle {private int radius = 10;private String backgroundColor = "#FF0000";private String borderColor = "#000000";private double scaleFactor = 0.5;...// getter / setter
}

序列化(Java对象–> JSON)可以如下进行:

Circle circle = new Circle();
Gson gson = new Gson();
String json = gson.toJson(circle); 
==> json is
{"radius": 10,"backgroundColor": "#FF0000","borderColor": "#000000","scaleFactor": 0.5,...
}

反序列化(JSON –> Java对象)只是一行代码:

Circle circle2 = gson.fromJson(json, Circle.class);  
==> circle2 is the same as the circle above

一切都像魅力。 我只遇到抽象类一个问题。 假设,我们有一个抽象类AbstractElement和许多其他类来扩展这一类

public abstract class AbstractElement {private String uuid;// getter / setter
}public class Circle extends AbstractElement {...
}public class Rectangle extends AbstractElement {...
}public class Ellipse extends AbstractElement {...
}

现在假定,我们将所有具体类存储在使用AbstractElement参数化的列表或映射中

public class Whiteboard
{private Map<String, AbstractElement> elements = new LinkedHashMap<String, AbstractElement>();...
}

问题是在反序列化期间未公开具体类。 在Whiteboard的JSON表示中未知。 如何从JSON表示形式实例化正确的Java类并将其放入Map <String,AbstractElement>元素中? 我在文档中找不到解决该问题的方法。 显然,我们需要在有关具体类的JSON表示中存储元信息。 这是肯定的。 Gson允许您注册自己的自定义序列化器和反序列化器。 这是Gson的强大功能。 有时默认表示不是您想要的。 例如在处理第三方库类时,通常就是这种情况。 有足够的示例说明如何编写自定义序列化器/反序列化器。 我将创建一个实现两个接口JsonSerializer,JsonDeserializer的适配器类,并将其注册为我的抽象类AbstractElement。

GsonBuilder gsonBilder = new GsonBuilder();
gsonBilder.registerTypeAdapter(AbstractElement.class, new AbstractElementAdapter());
Gson gson = gsonBilder.create();

这是AbstractElementAdapter:

package com.googlecode.whiteboard.json;import com.google.gson.*;
import com.googlecode.whiteboard.model.base.AbstractElement;
import java.lang.reflect.Type;public class AbstractElementAdapter implements JsonSerializer<AbstractElement>, JsonDeserializer<AbstractElement> {@Overridepublic JsonElement serialize(AbstractElement src, Type typeOfSrc, JsonSerializationContext context) {JsonObject result = new JsonObject();result.add("type", new JsonPrimitive(src.getClass().getSimpleName()));result.add("properties", context.serialize(src, src.getClass()));return result;}@Overridepublic AbstractElement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)throws JsonParseException {JsonObject jsonObject = json.getAsJsonObject();String type = jsonObject.get("type").getAsString();JsonElement element = jsonObject.get("properties");try {return context.deserialize(element, Class.forName("com.googlecode.whiteboard.model." + type));} catch (ClassNotFoundException cnfe) {throw new JsonParseException("Unknown element type: " + type, cnfe);}}
}

我添加了两个JSON属性-一个是“类型”,另一个是“属性”。 第一个属性保存AbstractElement的具体实现类(简单名称),第二个属性保存序列化对象本身。 JSON看起来像

{"type": "Circle","properties": {"radius": 10,"backgroundColor": "#FF0000","borderColor": "#000000","scaleFactor": 0.5,...}
}

反序列化期间,我们受益于“类型”属性。 现在可以通过Class.forName(“ com.googlecode.whiteboard.model。” + type)实例化具体类,其中“ com.googlecode.whiteboard.model”。 + type是完全限定的类名。 以下通话

public <T> T deserialize(JsonElement json, Type typeOfT) throws JsonParseException

JsonDeserializationContext中的from会在指定对象上调用默认的反序列化并完成作业。

参考: 带有GSON的JSON和来自JCG合作伙伴 Oleg Varaksin的抽象类 , 位于软件开发博客上。


翻译自: https://www.javacodegeeks.com/2012/04/json-with-gson-and-abstract-classes.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372991.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解javascript原型和闭包(3)——prototype原型

转载&#xff0c;原文地址http://www.cnblogs.com/wangfupeng1988/p/3978131.html 既typeof之后的另一位老朋友&#xff01; prototype也是我们的老朋友&#xff0c;即使不了解的人&#xff0c;也应该都听过它的大名。如果它还是您的新朋友&#xff0c;我估计您也是javascript的…

python 温度 符号_Python通过小实例入门学习---1.0(温度转换)

1.安装Python 3 下载地址: Welcome to Python.org​www.python.org 2.“温度转换”实例:摄氏度--->华氏度 / 华氏度--->摄氏度 TempConvert.py TempStr = input("请输入带有符号的温度值:") if TempStr[-1] in ["f","F"]:C = (eval(Tem…

mysql 修改root密码

1.找到配置文件my.ini &#xff0c;然后将其打开&#xff0c;可以选择用记事本打开 C:\Program Files (x86)\MySQL\MySQL Server 5.0 2.打开后&#xff0c;搜索mysqld关键字&#xff0c;找到后&#xff0c;在mysqld下面添加skip-grant-tables&#xff0c;保存退出。 PS&#x…

联想计算机CDROM启动,联想电脑光驱启动问题?

1、开机按del键或f2进入bios设置(不同主板按键不一样&#xff0c;一般是DEL&#xff0c;也可能是F2&#xff0c;可以参考下主板说明)&#xff0c;将计算机的启动模式调成从光盘启动。也就是从cdrom启动&#xff0c;根据主板的不同&#xff0c;bios设置有所差异(一般是&#xff…

没有J2EE容器的JNDI和JPA

我们希望通过尽可能简单的设置来测试一些JPA代码。 计划仅使用Java和Maven&#xff0c;不使用应用程序服务器或其他J2EE容器。 我们的JPA配置需要两件事才能成功运行&#xff1a; 数据库来存储数据&#xff0c; JNDI访问数据库。 这篇文章分为两个部分。 第一部分显示了如何…

string 大小写转换

STL的algorithm库确实给我们提供了这样的便利&#xff0c;使用模板函数transform可以轻松解决这个问题&#xff0c;开发人员只需要提供一个函数对象&#xff0c;例如将char转成大写的toupper函数或者小写的函数tolower函数。 transform原型&#xff1a; 1 #include <string&…

linux服务器上svn的log_如何在 Centos 8 / RHEL 8 上安装和配置 VNC 服务器 | Linux 中国...

在 Centos 8 和 RHEL 8 系统中&#xff0c;默认未安装 VNC 服务器&#xff0c;它需要手动安装。在本文中&#xff0c;我们将通过简单的分步指南&#xff0c;介绍如何在 Centos 8 / RHEL 8 上安装 VNC 服务器。-- Pradeep KumarVNC(虚拟网络计算Virtual Network Computing)服务器…

怎么把网页保存到本地计算机,在IE浏览器中,将网页保存到本地计算机中,若只需保存其中的文字、超链接和表格信息,应该选择的保存类型为( )...

2.(2017高一上东台月考)阅读下面一段资料&#xff0c;判断在给出的几种说法中不正确的是( )资料&#xff1a;IP电话与传统电话IP电话是按国际互联网协议规定的网络技术内容开通的电话业务&#xff0c;中文翻译为网络电话或互联网电话&#xff0c;它是利用国际互联网Inetrnet为…

html_博客博主

csdn: 工匠若水 http://blog.csdn.net/yanbober yunama: IT蓝豹&#xff1a;http://www.itlanbao.com/&#xff1b; http://ask.dcloud.net.cn/docs/; 博客园&#xff1a; https://www.cnblogs.com/guweiwei/category/965437.html转载于:https://www.cnblogs.com/awkflf11/p/55…

Windows上的Java线程CPU分析

本文将为您提供一个教程&#xff0c;介绍如何在Windows OS上快速查明Java线程贡献者与CPU严重问题有关。 Windows与Linux&#xff0c;Solaris和AIX等其他操作系统一样&#xff0c;使您可以在进程级别监视CPU利用率&#xff0c;还可以监视在进程中执行任务的单个线程。 在本教程…

flask 继承模版的基本使用1

转载于:https://www.cnblogs.com/wanghaonull/p/6399492.html

东芝2303am维护清零_东芝打印机2303A怎样清零

展开全部东芝e68a843231313335323631343130323136353331333365653137打印机是按照相关要求生产的正规产品&#xff0c;其清零方式与正规产品相同。因此此处将介绍常用的打印机清零方法。打印机清零一般分两种&#xff1a;一种是手工清零&#xff0c;另一种是软件清零。一、手工…

计算机日期函数公式大全,Excel技巧: 根据日期汇总月份的计算公式

在许多情况下&#xff0c;Excel记录的数据将按照发生的日期进行记录&#xff0c;但是根据日期记录的数据将非常分散&#xff0c;通常需要每月汇总相应的数据. 在这种情况下&#xff0c;您需要将日期转换为月份. 本文介绍了如何使用SUMPRODUCT函数按月汇总数据.公式提示在SUMPRO…

Java陷阱:内部类中的字段访问

这本身不是一个“陷阱”&#xff0c;而是一个值得了解的实现细节。 假设我有一个带有字段的内部类。 这样的字段对于封闭的类是可见的&#xff0c;但是以下哪种方法是访问它的最快方法&#xff1f; 注意&#xff01; 我只在这里查看生成的字节码&#xff0c;而不考虑任何JIT优化…

coverity代码检测工具介绍_微服务测试之静态代码扫描

静态代码扫描为整个发展组织增加价值。无论您在开发组织中发挥的作用如何&#xff0c;静态代码扫描解决方案都具有附加价值&#xff0c;拥有软件开发中所需要的尖端功能&#xff0c;最大限度地提高质量并管理软件产品中的风险。背景微服务架构模式具有服务间独立&#xff0c;可…

XML引入以及与html的区别

1.1 引入HTML: 负责网页的结构 CSS&#xff1a; 负责网页的样式&#xff08;美观&#xff09;Javascript&#xff1a; 负责在浏览器端与用户进行交互。负责静态的网页制作的语言HTML语言特点&#xff1a;1&#xff09;由标签组成。 <title> <p> <hr/> <br…

ADF:在任务流终结器中支持bean作用域

介绍 当我们需要在任务流消失之前完成一些最终工作&#xff08;干净的资源&#xff0c;紧密的连接等&#xff09;时&#xff0c;这是使用任务流终结器的非常普遍的推荐做法。 和往常一样&#xff0c;我们使用在任务流中声明的托管bean。 托管Bean可以具有不同的范围-请求&#…

Python 异常处理--raise函数用法

在Python中&#xff0c;要想引发异常&#xff0c;最简单的形式就是输入关键字raise&#xff0c;后跟要引发的异常的名称。异常名称标识出具体的类&#xff1a; Python异常处理是那些类的对象。执行raise语句时&#xff0c;Python会创建指定的异常类的一个对象。raise语句还可指…

大学计算机教学ppt数制,大学计算机基础 第3讲 数制及其相互转换 国家精品课程课件(可编辑)...

大学计算机基础第3讲数制及其相互转换国家精品课程课件PPT第1 章计算机基础知识第3 讲数制及其相互转换主要教学内容数制的基本概念1 数制转换2 小结3 学习目标1 理解数制的基本概念。2 掌握数制间的转换。3 能够灵活应用转换关系完成数制之间的转换。重点与难点不同数制之间的…

linux中匿名用户怎么登陆_南京课工场IT培训:Linux中vsftpd服务配置(匿名,用户,虚拟用户)...

vsftpd概述vsftpd 是“very secure FTP daemon”的缩写&#xff0c;安全性是它的一个最大的特点。vsftpd 是一个 UNIX 类操作系统上运行的服务器的名字&#xff0c;它可以运行在诸如 Linux、BSD、Solaris、 HP-UNIX等系统上面&#xff0c;是一个完全免费的、开放源代码的ftp服务…