Gson——用java-JSON实现序列化和反序列化

原文链接:Getting Started with Java-JSON Serialization & Deserialization

作者:Norman Peitek

翻译:签到钱就到

在发布了50多篇Retrofit的文章之后,收到很多读者的反馈,要求我们对Google的Gson做一个扩展介绍。Gson是一个将JSON格式的数据结构映射成java对象的非常强大的库。当然,它也支持其他组织的方式,并且也能为你的java对象创建合适的JSON表示形式。

如果你对我们正在进行的这个系列感兴趣,请浏览一下下面的大纲。

Gson系列概览

  1. Gson——用java-JSON实现序列化和反序列化
  2. Mapping of Nested Objects
  3. Mapping of Arrays and Lists of Objects
  4. Mapping of Maps
  5. Mapping of Sets
  6. Mapping of Null Values
  7. Gson Model Annotations — How to Ignore Fields with @Expose
  8. Gson Model Annotations — How to Change the Naming of Fields with @SerializedName
  9. Gson Builder — Basics & Naming Policies
  10. Gson Builder — Force Serialization of null Values
  11. Gson Builder — Exclusion Strategies
  12. Gson Builder — Relax Gson with Lenient
  13. Gson Builder — Special Values of Floats & Doubles
  14. Gson Builder — Model Versioning
  15. Gson Builder — Formatting of Dates & Custom Date/Time Mapping
  16. Gson Builder — Pretty Printing
  17. Gson Builder — HTML Escaping

Gson 依赖

本指南将要着手,首先在一分钟内完成一些序列化的准备工作。
由于大多数读者都是Android开发者,我们会为你量身定制,但是Gson也能被用在任何Java环境中。在我们开始之前,我们需要将Gson库拖到我们的项目工程中。截止到写作时间,最新的版本是2.6.2。如果你正在使用Gradle,添加下面的代码:

compile 'com.google.code.gson:gson:2.6.2'  

如果你正在使用Maven,你可以添加下面的依赖:

<dependencies>  
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.6.2</version>
        <scope>compile</scope>
    </dependency>
</dependencies>  

对于那些都没有使用依赖环境系统的可怜家伙,你可以从官方的Github仓库里下载jar包。

Java-JSON序列化基础

让我们做一些系列化!在Gson中序列化是指映射一个java对象到它的JSON表达。在后续的教程中,我们的数据将会变得更复杂,但是我们现在只要从一些非常简单的UserSimple开始:

public class UserSimple {  
    String name;
    String email;
    int age;
    boolean isDeveloper;
}

user对象有四个属性:

  • user的 name 是一个 String 对象
  • user的 email 是一个 String 对象
  • user的 age 是一个 integer, 表明是按年来表示的(例如 26 ,并非准确的生日!)
  • 一个 boolean 标签 isDeveloper

我们的Android或java应用需要转换一个UserSimple对象到它的JSON表示。假设我们保持成员变量名字一致,我们会为Norman(这篇文章的作者)准备这样的JSON表示:

{
  "name": "Norman",
  "email": "norman@futurestud.io",
  "age": 26,
  "isDeveloper": true
}

让我们研究怎么用Gson完成转换。首先,我们需要为Norman创建一个Java对象。

UserSimple userObject = new UserSimple(  
    "Norman", 
    "norman@futurestud.io", 
    26, 
    true
);

译者注:如果没有在UserSimple类里添加对应的构造函数,上面会报错。添加也很简单,UserSimple类内部编辑界面,右键—>Generate->Constructor->全部选中 ,点击ok。自动生成如下代码:

public UserSimple(String name, String email, int age, boolean isDeveloper) {
    this.name = name;
    this.email = email;
    this.age = age;
    this.isDeveloper = isDeveloper;
}

为了完成序列化,我们需要一个Gson对象来操作转换。我们可以简单的使用下面的创建:

Gson gson = new Gson(); 

为了开始序列化,我们需要调用toJson()方法,然后传递UserSimple对象:

String userJson = gson.toJson(userObject);  

userJson对象包含了下面的值:

{
  "age": 26,
  "email": "norman@futurestud.io",
  "isDeveloper": true,
  "name": "Norman"
}

Gson改变了属性的顺序(按字母顺序),但是内容是一样的!注意Gson是如何表示这些类型的。String值用“”包裹,但integer值却没有包裹。我们不需要在JSON对象或复制单个成员上浪费时间。一个Gson的简单调用足以映射整个对象。当我们处理非常复杂的数据结构时,这是非常方便的。但在我们进一步深入之前,我们测试另一个方向。Gson可以从上面的JSON数据中创建一个java对象么?

java-JSON 反序列化基础

首先,我们需要创建一个字符串,包含上面提到的JSON:

String userJson = "{'age':26,'email':'norman@futurestud.io','isDeveloper':true,'name':'Norman'}";  

我们将 "变为 ' ,是为了避免大量的\"转义。它就是这样工作的。下一步,可能你已经猜到了,创建一个Gson实例:

Gson gson = new Gson(); 

最后,我们必须用fromJson()映射一个JSON到一个Java对象:

UserSimple userObject = gson.fromJson(userJson, UserSimple.class);   

注意我们是怎样将Java对象作为第二个参数进行传递。否则Gson不知道应该将JSON映射。它不是一个魔术师!

如果我们添加了一个debugger并且检查了user对象的结果,它会展示Gson成功地准确映射了所有属性:

计划 与 展望

看完这篇引导文章后,你应该已经了解了Gson的基本使用。我们已经展示了如何简单地完成JSON数据与Java的映射。我们也知道你此刻肯定有大量的问题要问:

  • Java模型类需要一个constructor/getter/setter么?
  • Java模型字段可以是私有(private)的么?
  • 怎样处理空值(null values)?
  • 对于JSON数据,如果Java类有不同的变量命名怎么办?
  • 如何序列化(反序列化)对象数组/列表?
  • 如何序列化(反序列化)嵌套对象?
  • 当执行.fromJson()时,JSON数据中获取不到某个属性的值,Gson会为其保留一个默认的值么?

没必要担心,我们会在后续的文章中一一解答。如果你有特别的主题,在下面的评论中或twitter@futurestud_io让我们知道。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容