Gson详细使用,此Gson非彼Json,你值得拥有~
2016-03-21 23:15
471 查看
额~先来一句官方的话
Gson是谷歌推出的解析json数据以及将对象转换成json数据的一个开源框架. 现在json因其易读性和高效率而被广泛的使用着. 相对于java以及其它json的解析框架,Gson非常的好用.
熟悉网络编程的人知道,网络请求返回的数据格式一般要么是json,要么是xml,但是采用json格式这种方式是使用的最为广泛的。网络请求返回的json数据时,使用JSONObject或者JSONArray来承载数据,然后把返回的数据当作一个字典,根据键取出相应的值。
现在假如网络请求返回这样一个数据:
{
“city”: “北京”,
“cityId”: “10000000001”,
“temp”: “24”,
“wd”: “南风”,
“ws”: “2级”,
“sd”: “74%”,
“wse”: “2”,
“time”: “17:45”,
“isReader”: “1”,
“Radar”: “JC_RADAR_AZ9010_JB”,
“njd”: “暂无实况\t”,
“qy”: “1005”
}
那么在使用Json在解析这段数据的时候是依据每一个Key来取值的。
那我们要一次知道如下一些键值key才能取到相应的value.
city ,cityId,temp,wd,ws,sd,wse,time,isReader,Radar;
如果在做项目的时候后台给的接口不是很多,那么采用这种方式还是可以接受的,如果后台接口没有设计好,可能要改变几个接口,增添若干个字段,或删除若干个字段,那么对于前端开发人员来说这是难以接受的,而且对于整个项目来说也是非常难以接受,对于这样的后台开发者来说,我个人觉得那是要拖出来枪毙的,因为接口一改变,对于大一点的项目来说,Android,IOS,Web,微信等等前端开发,都需要进行相应的改变,需要改变重新调整数据实体和修改相应json解析,如果项目很大的话,即便修改一点点也是非常耗时间的。曾经年少无知做过这样的项目,还好和自己的好朋友同学一起开发,不过也因此发生过严重的争执,感谢自己的当时的忍耐,没有打起来。不过现在仍然是好朋友^_^.如果当时要是知道了有Gson这吊炸天的玩意儿,也许就不会发生那么多不愉快的事情了,当然现在不仅仅只有Gson,还有fastJson也有同样的功能,好吧,下面我们来看看Gson是如何的吊炸天。
在此之前,我们需要准备gson.jar
可以到官网下载:
http://mvnrepository.com/artifact/com.google.code.gson/gson
点击下载
我下载的是最新的,2.6.2版本的,链接不上的也可以直接在这里下载
好了现在开始讲解介绍gson了
1.在调用JSON操作时,gson实例不维护任何状态。所以,你可以重复使用同一对象的多个JSON序列化和反序列化操作。
(Serialization)序列化操作如下:
import com.google.gson.Gson; public class Demo04 { public static void main(String[] args) { Gson gson = new Gson(); String s = gson.toJson(11111); System.out.println("(11111)->"+s); s = gson.toJson("abcdefg"); System.out.println("(abcd)->"+s); s = gson.toJson(new Long(10)); System.out.println("(10)->"+s); int[] values = { 1 ,2,3,4,5,6}; s = gson.toJson(values); System.out.println("(1 ,2,3,4,5,6)->"+s); } }
控制台输出:
(11111)->11111
(abcd)->”abcdefg”
(10)->10
(1 ,2,3,4,5,6)->[1,2,3,4,5,6]
(Deserialization)反序列化操作如下:
import java.util.List; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; public class Demo05 { public static void main(String[] args) { // TODO Auto-generated method stub Gson gson = new Gson(); int one = gson.fromJson("1", int.class); System.out.println("one:" + one); Integer integer = gson.fromJson("1", Integer.class); System.out.println("integer:" + integer); Long long1 = gson.fromJson("1", Long.class); System.out.println("long1:" + long1); Boolean boolean1 = gson.fromJson("false", Boolean.class); System.out.println("boolean1:" + boolean1); String str = gson.fromJson("\"abc\"", String.class); System.out.println("str:" + str); List<String> list = gson.fromJson("[\"abc\",\"def\"]", new TypeToken<List<String>>() { }.getType()); System.out.println("list:" + list); } }
控制台输出:
one:1
integer:1
long1:1
boolean1:false
str:abc
list:[abc, def]
2.(对象例子)Object Examples
实体如下:
package domain; import java.util.Date; public class Student { private int id; private String name; private Date birthDay; public Student(){} public Student(int id, String name, Date birthDay) { super(); this.id = id; this.name = name; this.birthDay = birthDay; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthDay() { return birthDay; } public void setBirthDay(Date birthDay) { this.birthDay = birthDay; } public String toString() { return "Student [birthDay=" + birthDay + ", id=" + id + ", name=" + name + "]"; } }
(Serialization)序列化操作如下:
import com.google.gson.Gson; public class Demo03 { public static void main(String[] args) { // TODO Auto-generated method stub Weather w = new Weather("北京", "10000000001", "24", "南风", "2级", "74%", "2", "17:45", "1", "JC_RADAR_AZ9010_JB", "暂无实况 ", "1005"); Gson gson = new Gson(); System.out.println(gson.toJson(w)); } }
控制台输出(手动转成Json格式):
{
“city”: “北京”,
“cityId”: “10000000001”,
“temp”: “24”,
“wd”: “南风”,
“ws”: “2级”,
“sd”: “74%”,
“wse”: “2”,
“time”: “17:45”,
“isReader”: “1”,
“Radar”: “JC_RADAR_AZ9010_JB”,
“njd”: “暂无实况\t”,
“qy”: “1005”
}
(Deserialization)反序列化操作如下:
import com.google.gson.Gson; public class Demo03 { public static void main(String[] args) { // TODO Auto-generated method stub Weather w = new Weather("北京", "10000000001", "24", "南风", "2级", "74%", "2", "17:45", "1", "JC_RADAR_AZ9010_JB", "暂无实况 ", "1005"); Gson gson = new Gson(); String json = gson.toJson(w); System.out.println("json输出:"+json); System.out.println("-----------------------------------------"); Weather w2 = gson.fromJson(json, Weather.class); System.out.println("对象输出:"+w2); } }
控制台输出:
json输出(便于观察,转成json格式排版): { "city": "北京", "cityId": "10000000001", "temp": "24", "wd": "南风", "ws": "2级", "sd": "74%", "wse": "2", "time": "17:45", "isReader": "1", "Radar": "JC_RADAR_AZ9010_JB", "njd": "暂无实况\t", "qy": "1005" } ----------------------------------------- 对象输出(便于观察,转成json格式排版,实际toString): Weather[ city=北京, cityId=10000000001, temp=24, wd=南风, ws=2级, sd=74%, wse=2, time=17: 45, isReader=1, Radar=JC_RADAR_AZ9010_JB, njd=暂无实况, qy=1005 ]
3.现在来个稍微复杂一点的包含内部类
实体如下(BoyStudent 包含Student内部类):
public class Student { private int id; private String name; private Date birthDay; public Student(){} public Student(int id, String name, Date birthDay) { super(); this.id = id; this.name = name; this.birthDay = birthDay; } public String toString() { return "Student [birthDay=" + birthDay + ", id=" + id + ", name=" + name + "]"; } } public class BoyStudent { private String sex; private String intertests; private Student student; @Override public String toString() { return "Boy [sex=" + sex + ", intertests=" + intertests + ", student=" + student + "]"; } public Boy(String sex, String intertests, Student student) { super(); this.sex = sex; this.intertests = intertests; this.student = student; } public Boy() { } }
(Serialization)序列化,(Deserialization)反序列化操作操作如下:
public static void main(String[] args) { // TODO Auto-generated method stub Gson gson = new Gson(); Student s1 = new Student(1,"s1",new Date()); BoyStudent b1 = new BoyStudent("m", "篮球", s1); String json1 = gson.toJson(b1); System.out.println("json1:"+json1); System.out.println("---------------------------"); BoyStudent bTemp = gson.fromJson(json1, BoyStudent.class); System.out.println("bTemp:"+bTemp); }
输出:
json1: { "sex": "m", "intertests": "篮球", "student": { "id": 1, "name": "s1", "birthDay": "Mar 21, 2016 9:44:05 PM" } } --------------------------- bTemp: BoyStudent[ sex=m, intertests=篮球, student=Student[ birthDay=MonMar2121: 44: 05CST2016, id=1, name=s1 ] ]
4.在开发中那么这还是仅仅不够的,进场返回来的json数据是一个集合,那么gson能否实现呢?哈哈~那是必须的,现在来个复杂一点的。
实体如下:
public class ResponseBoyStudent { private int errCode; private String note; private BoyStudent boyStudent; public ResponseBoyStudent(int errCode, String note, BoyStudent boyStudent) { super(); this.errCode = errCode; this.note = note; this.boyStudent = boyStudent; } @Override public String toString() { return "ResponseBoyStudent [errCode=" + errCode + ", note=" + note + ", boyStudent=" + boyStudent + "]"; } }
(Serialization)序列化,(Deserialization)反序列化操作操作如下:
public static void main(String[] args) { // TODO Auto-generated method stub Student s1 = new Student(1, "TFboys-1", new Date()); Student s2 = new Student(2, "TFboys-2", new Date()); Student s3 = new Student(3, "TFboys-3", new Date()); BoyStudent b1 = new BoyStudent("M", "唱歌", s1); BoyStudent b2 = new BoyStudent("M", "跳舞", s2); BoyStudent b3 = new BoyStudent("M", "啥都不会", s3); ResponseBoyStudent rbs1 = new ResponseBoyStudent(200, "Ok", b1); ResponseBoyStudent rbs2 = new ResponseBoyStudent(302, "跳转", b2); ResponseBoyStudent rbs3 = new ResponseBoyStudent(404, "资源请求失败", null); List<ResponseBoyStudent> tfboys = new ArrayList<ResponseBoyStudent>(); tfboys.add(rbs1); tfboys.add(rbs2); tfboys.add(rbs3); Gson gson = new Gson(); String json = gson.toJson(tfboys); System.out.println(json); System.out.println("--------------------------------"); List<ResponseBoyStudent> rec_tfboys = gson.fromJson(json, new TypeToken<List<ResponseBoyStudent>>() { }.getType()); System.out.println(rec_tfboys); }
控制台输出:
[ { "errCode": 200, "note": "Ok", "boyStudent": { "sex": "M", "intertests": "唱歌", "student": { "id": 1, "name": "TFboys-1", "birthDay": "Mar 21, 2016 10:06:54 PM" } } }, { "errCode": 302, "note": "跳转", "boyStudent": { "sex": "M", "intertests": "跳舞", "student": { "id": 2, "name": "TFboys-2", "birthDay": "Mar 21, 2016 10:06:54 PM" } } }, { "errCode": 404, "note": "资源请求失败" } ] -------------------------------- [ ResponseBoyStudent[ errCode=200, note=Ok, boyStudent=BoyStudent[ sex=M, intertests=唱歌, student=Student[ birthDay=MonMar2122: 06: 54CST2016, id=1, name=TFboys-1 ] ] ], ResponseBoyStudent[ errCode=302, note=跳转, boyStudent=BoyStudent[ sex=M, intertests=跳舞, student=Student[ birthDay=MonMar2122: 06: 54CST2016, id=2, name=TFboys-2 ] ] ], ResponseBoyStudent[ errCode=404, note=资源请求失败, boyStudent=null ] ]
看到这里有木有想哭的赶脚,之前写的代码真叫尼玛一个累~
注意:好好观察哦,当404传入为空的时候,在生成Json字符串是没有boyStudent这个键值的,同时当反序列化为list对象时boyStudent是为空的!
好了看到这里,会想到另外一种需求,BoyStudent不能为空,而且它是有默认值的,但是返回来的却是null,那么在程序中像这样rec_tfboys.get(postion).getBoyStudent().get….使用是一定会报空指针异常的。总不至于不让后台传入空值吧?会不会有其他的解决办法呢?带着问题思考,既然提到这里了,答案一定是有的,再次之前就说Gson吊炸天了吧!我说的没错吧,废话不多说,直接来码代码吧~^_^
我对几个实体类稍微做了一下修改,注意观察修改了那些内容,注意哪些是变化的,哪些是没有变化的
public class Student { private int id; private String name; private Date birthDay; /////////////////////Change///////////////////////////// public Student(){ this.id = 0; this.name = "请输入您的姓名"; this.birthDay = new Date(); } /////////////////////Change///////////////////////////// public Student(int id, String name, Date birthDay) { super(); this.id = id; this.name = name; this.birthDay = birthDay; } public String toString() { return "Student [birthDay=" + birthDay + ", id=" + id + ", name=" + name + "]"; } } public class BoyStudent { private String sex; private String intertests; private Student student; @Override public String toString() { return "BoyStudent [sex=" + sex + ", intertests=" + intertests + ", student=" + student + "]"; } public BoyStudent(String sex, String intertests, Student student) { super(); this.sex = sex; this.intertests = intertests; this.student = student; } /////////////////////Change///////////////////////////// public BoyStudent() { this.sex = "M"; this.intertests = "左手右手一个慢动作"; this.student = new Student(1000, "请输入您的姓名", new Date()); } /////////////////////Change///////////////////////////// } public class ResponseBoyStudent { private int errCode; private String note; private BoyStudent boyStudent; public ResponseBoyStudent(int errCode, String note, BoyStudent boyStudent) { super(); this.errCode = errCode; this.note = note; this.boyStudent = boyStudent; } /////////////////////Change///////////////////////////// public ResponseBoyStudent(){ boyStudent = new BoyStudent("M","睡觉",new Student()); } ////////////////////////////////////////////////// @Override public String toString() { return "ResponseBoyStudent [errCode=" + errCode + ", note=" + note + ", boyStudent=" + boyStudent + "]"; } }
我将用斜线表示出来改变的部分,一次是对其无参构造函数进行了修改,我们来看看效果是否如我们所想那样。
序列化反序列化操作操作代码未进行修改。
控制台输出:
[ { "errCode": 200, "note": "Ok", "boyStudent": { "sex": "M", "intertests": "唱歌", "student": { "id": 1, "name": "TFboys-1", "birthDay": "Mar 21, 2016 10:41:43 PM" } } }, { "errCode": 302, "note": "跳转", "boyStudent": { "sex": "M", "intertests": "跳舞", "student": { "id": 2, "name": "TFboys-2", "birthDay": "Mar 21, 2016 10:41:43 PM" } } }, { "errCode": 404, "note": "资源请求失败" } ] -------------------------------- [ ResponseBoyStudent[ errCode=200, note=Ok, boyStudent=BoyStudent[ sex=M, intertests=唱歌, student=Student[ birthDay=MonMar2122: 41: 43CST2016, id=1, name=TFboys-1 ] ] ], ResponseBoyStudent[ errCode=302, note=跳转, boyStudent=BoyStudent[ sex=M, intertests=跳舞, student=Student[ birthDay=MonMar2122: 41: 43CST2016, id=2, name=TFboys-2 ] ] ], ResponseBoyStudent[ errCode=404, note=资源请求失败, boyStudent=BoyStudent[ sex=M, intertests=睡觉, student=Student[ birthDay=MonMar2122: 41: 43CST2016, id=0, name=请输入您的姓名 ] ] ] ]
**可以发现json字符串未发生改变,但是反序列化的list的内容都是部位空的,可以推出,json字符串中缺少键值的时候仍会去“调用”默认构造函数。
5.既然能让空的json反序列话为不为null的实例,那能不能返回null?不买关子了,是有的^_^.
代码很简单:
public static void main(String[] args) { // TODO Auto-generated method stub Gson gson = new GsonBuilder().serializeNulls().create(); String json = gson.toJson(null); System.out.println(json); }
控制台输出:
null
为什么非要去Builder一个Gson实例呢,难道直接new 出来的不可以吗?亲测确实可以,但是这两种方式有什么区别呢?
public static void main(String[] args) { // TODO Auto-generated method stub Gson gson = new Gson(); String json = gson.toJson(null); System.out.println(json); }
控制台输出:
null
好,那我么就来观察它的区别吧!
直接上代码了
实体如下:
public class Foo { private final String s; private final int i; public Foo() { this(null, 5); } public Foo(String s, int i) { this.s = s; this.i = i; } @Override public String toString() { return "Foo [s=" + s + ", i=" + i + "]"; } }
(Serialization)序列化,(Deserialization)反序列化操作操作如下:
先看直接new出来的Gson
public static void main(String[] args) { // TODO Auto-generated method stub Gson gson = new Gson(); Foo foo = new Foo(); String json = gson.toJson(foo); System.out.println(json); Foo f = gson.fromJson(json, Foo.class); System.out.println("f:"+f); json = gson.toJson(null); System.out.println(json); }
控制台输出:
{"i":5} f:Foo [s=null, i=5] null
在biu~出来的效果
public static void main(String[] args) { // TODO Auto-generated method stub Gson gson = new GsonBuilder().serializeNulls().create(); Foo foo = new Foo(); String json = gson.toJson(foo); System.out.println(json); Foo f = gson.fromJson(json, Foo.class); System.out.println("f:"+f); json = gson.toJson(null); System.out.println(json); }
控制台输出:
{"s":null,"i":5} f:Foo [s=null, i=5] null
看出二者的区别了吧,当使用biu~方式时属性为空的时候输出来的json字符串是有键值key的,而直接new出来的就没有。
非常感谢看到这里的朋友,最后送点一个非常实用的工具给你
这个工具叫做json实体转换器,用法很简单,我直接贴图就好了。
确认提交之后将自动生成相应的实体
看看生成的实体张什么样子吧
工具下载地址:http://download.csdn.net/detail/u013922681/9468715
package domain; import java.lang.reflect.Field; import java.io.Serializable; import java.util.List; public class JavaName implements Serializable { public String note; public int errCode; public BoyStudent boyStudent; public class BoyStudent implements Serializable { public String sex; public String intertests; public Student student; public class Student implements Serializable { public String birthDay; public String name; public int id; public void setBirthDay(String birthDay) { this.birthDay = birthDay; } public String getBirthDay() { return this.birthDay; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setId(int id) { this.id = id; } public int getId() { return this.id; } public String toString() { String s = ""; Field[] arr = this.getClass().getFields(); for (Field f : getClass().getFields()) { try { s += f.getName() + "=" + f.get(this) + "\n,"; } catch (Exception e) { } } return getClass().getSimpleName() + "[" + (arr.length == 0 ? s : s.substring(0, s.length() - 1)) + "]"; } } public void setSex(String sex) { this.sex = sex; } public String getSex() { return this.sex; } public void setIntertests(String intertests) { this.intertests = intertests; } public String getIntertests() { return this.intertests; } public String toString() { String s = ""; Field[] arr = this.getClass().getFields(); for (Field f : getClass().getFields()) { try { s += f.getName() + "=" + f.get(this) + "\n,"; } catch (Exception e) { } } return getClass().getSimpleName() + "[" + (arr.length == 0 ? s : s.substring(0, s.length() - 1)) + "]"; } } public void setNote(String note) { this.note = note; } public String getNote() { return this.note; } public void setErrCode(int errCode) { this.errCode = errCode; } public int getErrCode() { return this.errCode; } public String toString() { String s = ""; Field[] arr = this.getClass().getFields(); for (Field f : getClass().getFields()) { try { s += f.getName() + "=" + f.get(this) + "\n,"; } catch (Exception e) { } } return getClass().getSimpleName() + "[" + (arr.length == 0 ? s : s.substring(0, s.length() - 1)) + "]"; } }
好了,第一次写这么认真~觉得可以的话点个赞!
对了,能看官网的demo就看官网的吧!
链接如下:https://sites.google.com/site/gson/gson-user-guide#TOC-Gson-Users
相关文章推荐
- Gson.toJson()时内存溢出StackOverflowError
- Android学习笔记45之gson解析json
- Android中gson、jsonobject解析JSON的方法详解
- JAVA使用Gson解析json数据实例解析
- Java中利用gson解析Json实例教程
- 利用gson将map转为json示例
- 在struts2 中使用jQuery 的Ajax 技术
- Gson的使用-android
- Gson详解:Java对象与JSON相互转换的利器
- 走在互联网的大陆上:一、几款流行的JSON库效率分析
- Gson简介和入门
- 关于Gson-2.4(自己犯得错误)
- GSON的JSON与对象+List的互转
- Android关于网络获取数据和解析数据
- Unable to execute dex: Multiple dex files define错误的一种解决方法
- JSON小小结 - - - jackson, gson, json-lib
- JSON小小结 - - - jackson, gson, json-lib
- 转载 Jackson 高性能的JSON处理 ObjectMapper
- volley 内部实现分析及二次封装
- Gson的数据解析