博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Gson详解:Java对象与JSON相互转换的利器
阅读量:6824 次
发布时间:2019-06-26

本文共 5469 字,大约阅读时间需要 18 分钟。

hot3.png

1. Gson是什么(What is Gson)

Gson是一个开源的Java库,用于任意Java对象与JSON之间的相互转换,由Google开发维护。

Gson的优势:

  • 简单易用:以toJsonfromJson两个方法为核心
  • 不需要annotations的支持,可以在缺少源代码或不方便修改源代码的情况下使用
  • 支持泛型和集合

github:

API Spec:

2. 将Gson引入项目

  • 在Maven中加入依赖
com.google.code.gson
gson
2.5
  • 将jar直接加入项目的lib文件夹

为了图省事,我把相应jar放在我的。(其实是把maven下载的版本打包而已)

3. 示例(How to use)

3.1 --自定义测试类--

public class Person implements Serializable, Comparable
{ private static final long serialVersionUID = 2373954257153196535L; private String name; private int age; private String gender; //实现Comparable只是为了测试Set的序列化/反序列化,并无其他意思 public int compareTo(Person o) { if(o == null) return -1; if(this == o) return 0; if(this.getName().equals(o.getName()) && this.getAge() == o.getAge() && this.getGender() == o.getGender()) return 0; return -1; } // a series of setter/getter}

3.2 序列化

Java对象 → JSON:toJson(Object)

Person p1 = new Person("David", 26, "male");Person p2 = new Person("Annie", 23, "female");Person p3 = new Person("琼恩", 29, "男");Gson gson = new Gson();//也可以通过new GsonBuilder().create();来实例化//单个对象String json = gson.toJson(p1);//{"name":"David","age":26,"gender":"male"}//ListList
list = Arrays.asList(p1, p2, p3);String jsonList = gson.toJson(list);//SetSet
set = new HashSet
();set.add(p1);set.add(p2);set.add(p1);String jsonSet = gson.toJson(set);//数组:先转换成ListPerson[] arr = {p1, p2, p3};List
jsonArrList = Arrays.asList(arr);String jsonArr = gson.toJson(jsonArrList);/* * 关于Java关键字:transient * * transient声明的field(成员变量)在对象序列化时会被忽略, * 常用于声明password之类比较敏感的变量。 * transient不能用于声明方法。(反正方法既不会也没必要被序列化) * * 由于gson.toJson(obj)涉及序列化,transient在此也会生效, * 即transient声明的变量不会出现在生成的json(String)中。(亲测) */

3.3 反序列化

JSON → Java对象:fromJson(String, Type)

  • 反序列化时,必须提供反序列化的类型java.lang.reflect.Type
  • 对于普通的引用类型(Object子类),可使用java.lang.Class对象(实现了Type接口)
Type t1 = Person.class;Type t2 = p1.getClass();boolean flag = (t1 == t2);//truePerson person = gson.fromJson(json, t1);System.out.println(person.getName());//David
  • 对于参数化类型(即泛型),可通过com.google.gson.reflect.TypeToken获取其类型
Type setType = new TypeToken
>(){}.getType();//TypeToken
的Constructor(构造器/构造方法)为protected, 使用匿名内部类的方式进行实例化Set
people = gson.fromJson(jsonSet, setType);Iterator
ps = people.iterator();while(ps.hasNext()){ System.out.println(ps.next().getName());}

3.4 重定向数据来源/输出

默认情况下,toJson(Object)将生成的JSON数据保存在一个StringWriter中;fromJson(String, Type)则是从String中读取。可传入相应WriterReader改变数据的去处或来源。

File f = new File("/Users/Lawrence/Documents/out.txt");Writer out = new FileWriter(f);gson.toJson(set, out);//将生成的JSON数据保存在文件中,而不是默认的Stringout.close();Reader reader = new FileReader(f);Set
setFromFile = gson.fromJson(reader, setType);//从文件中读取数据,而不是默认的StringSystem.out.println(setFromFile.size());//2reader.close();/* * 改变数据输出,需要java.lang.Appendable * 事实上Writer就实现了Appendable,所以其子类都满足这个条件 */

3.5 --修改自定义测试类--

Person类增加两个变量:

  • geo:长度为2的double数组用于表示地理位置,即经纬度
  • Account
public class Person implements Serializable, Comparable
{ private static final long serialVersionUID = 2373954257153196535L; private String name; private int age; private String gender; private double[] geo = new double[2]; private Account account; /* a series of setter/getter */}

Account.java:

public class Account {	private String id;	private String email;		private Date dateOfRegister = new Date();	/* setter/getter */}

3.6 自定义输出格式

通过修改GsonBuilder的属性,自定义输出的结果:

Person p1 = new Person("David", 26, "male");Account ac = new Account("id", "

test1@test1.com

");p1.setAccount(ac);Person p2 = new Person("Rose", 23, "女");Account ac2 = new Account("id2", "

test2@test2.com

");p2.setAccount(ac2);Person p3 = new Person();p3.setName("Hello");List
list = Arrays.asList(p1, p2, p3);Gson gson = new GsonBuilder() .setPrettyPrinting()//自动换行和添加缩进 .serializeNulls()//保留null的变量并将值设为null .disableHtmlEscaping()//不会对用于表示HTML标签的"<"和">"编码 .setDateFormat("yyyy-MM-dd")//为所有java.util.Date定义输出格式 .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES) //定义变量名的显示方式,如此处将Account的dateOfRegister定义输出为"Date Of Register" .create();System.out.println(gson.toJson(list));

以上输出为

[  {    "Name": "David",    "Age": 26,    "Gender": "male",    "Geo": [      0.0,      0.0    ],    "Account": {      "Id": "id",      "Email": "

test1@test1.com

", "Date Of Register": "2015-12-16" } }, { "Name": "Rose", "Age": 23, "Gender": "女", "Geo": [ 0.0, 0.0 ], "Account": { "Id": "id2", "Email": "

test2@test2.com

", "Date Of Register": "2015-12-16" } }, { "Name": "Hello", "Age": 0, "Gender": null, "Geo": [ 0.0, 0.0 ], "Account": null }]

3.7 操作JSON树

将3.6中添加的由3个Person对象组成的list为例:

JsonElement root = gson.toJsonTree(list);//3个Person对象if(root.isJsonArray()){	JsonArray arr = (JsonArray) root;	Iterator
iter = arr.iterator(); JsonElement target = null; while(iter.hasNext()){ JsonObject element = (JsonObject) iter.next(); String name = element.get("Name").getAsString(); if("Hello".equals(name)){// arr.remove(element);//不能调用ArrayList的remove(), 因为会抛出java.util.ConcurrentModificationException iter.remove();//需要调用的是Iterator的remove(); } }}System.out.println(gson.toJson(root));

4. 说明

以上内容均参考官方文档,如有错误,还望指正。

  • github:
  • API Spec:

转载于:https://my.oschina.net/SCVTheDefect/blog/545844

你可能感兴趣的文章
marquee知识点
查看>>
jQuery-DOM操作之创建、插入、删除元素
查看>>
自定义栈类型,具有找到站内最小元素的min函数 ,且min(),pop(),push()函数的时间复杂度为O(1)...
查看>>
redhat 5下源码安装nginx服务
查看>>
python优缺点分析及python种类,编码-课堂笔记及课后总结
查看>>
request和session作用域的意义
查看>>
大数据环境下互联网行业数据仓库/数据平台的架构之漫谈-续【转】
查看>>
SQLServer的最大连接数 超时时间已到 但是尚未从池中获取连接
查看>>
webpack学习笔记
查看>>
windows2008 RDP修改默认端口
查看>>
Nginx配置信息损毁又无备份时如何恢复
查看>>
libc.so.6: cannot open shared object file: No such file or diretory
查看>>
mysql oracle静默 一键安装脚本
查看>>
LINQ分页工具
查看>>
一张图让你明白IOS中bounds和frame的区别
查看>>
tex tab example
查看>>
week8
查看>>
mybatis 中文文档
查看>>
Docker学习笔记_进入正在运行的Docker容器
查看>>
Python tkinter 副窗体置顶和取消置顶
查看>>