帶有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.pswp.cn/news/372991.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/372991.shtml
英文地址,請注明出處:http://en.pswp.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服務…