Android json解析--GSON
2015-08-05 22:20
639 查看
转载请注明出处:http://blog.csdn.net/duanyy1990/article/details/47303631
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript(Standard
ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
Android的SDK中包含四个与JSON相关的类和一个Exceptions:JSONArray、JSONObject、JSONStringer、JSONTokener、JSONException。通过这5个类我们就可以自行对Json进行解析。但是通过他们读写Json还都要停留到手工操作上,无法直接实现Json字符串到对象、对象到Json字符串的转换,例如解析Json需要通过Key值一个一个的取Value,工作量大不说,还增加了出错的几率。有没有办法可以:直接实现Json字符串到对象、对象到Json字符串的转换?
Gson是对成员变量field进行序列化,Android恰恰是推荐开发者直接使用成员变量访问而不是用setter、getter。Gson可以很容易地实现对象与json字符串之间的相互转换。因此本文着重介绍Gson的用法。
先来看一下官方文档对Gson的概述。Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert
a JSON string to an equivalent Java object. Gson is an open-source project hosted at http://code.google.com/p/google-gson.这段话不复杂,想来大家都很容易理解,我就不过多解释了。
说了这么多如何使用呢?其实Gson用法很简单,但是却很强大。首先我们如果想要使用Gson就必须先创建一个Gson对象,有两种方式创建,一种是new Gson,一种是使用GsonBuilder来创建对象。官方文档的原话是这样的:The
primary class to use is Gson which
you can just create by calling new Gson(). There is also a class GsonBuilder available
that can be used to create a Gson instance with various settings like version control and so on. 创建的Gson对象可以通过单例模式一直使用。
接下来就是两个最主要的方法,toJson和fromJson。下面是官方文档提供的例子:
class
BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson =
new Gson();
String json = gson.toJson(obj);
==>
json is {"value1":1,"value2":"abc"}
Note that you can not serialize objects with circular references since that will result in infinite recursion.
(Deserialization)
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
是不是很方便。下面我总结了几种常用的转换关系:
1. 将json转换为对象
public static <T> T parseModel(String jsonStr, Class<T> cl) {
T obj = null;
if (gson != null) {
obj = gson.fromJson(jsonStr, cl);
}
return obj;
}
其中第二个参数只需要传Java类即可,例如MyClass.class
2. 将对象转换为json字符串
public static String objectToJson(Object ts) {
String jsonStr = null;
if (gson != null) {
jsonStr = gson.toJson(ts);
}
return jsonStr;
}
3. 将json字符串转换为List
public static <T> List<T> parseModelList(String jsonStr, com.google.gson.reflect.TypeToken<List<T>>
type) {
List<T> objList = null;
if (gson != null) {
objList = gson.fromJson(jsonStr, type.getType());
}
return objList;
}
4. 将List转换为json字符串
public static
String listToJson(List<?> list) {
String json = null;
if (gson != null) {
java.lang.reflect.Type type = new TypeToken<Map<?, ?>>() {}.getType();
json = gson.toJson(map, type);
}
returnjson;
}
5. 将json字符串转换为map
public static Map<?, ?> jsonToMap(String jsonStr) {
Map<?, ?> objMap = null;
if (gson != null) {
java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken<Map<?, ?>>() {
}.getType();
objMap = gson.fromJson(jsonStr, type);
}
return objMap;
}
6. 将map转换为json字符串
public staticString
mapToJson(Map<?, ?> map) {
String json = null;
if (gson != null) {
java.lang.reflect.Type type = new TypeToken<Map<?, ?>>() {}.getType();
json = gson.toJson(map, type);
}
return
json;
}
以上6中情况基本上可以满足正常的开发需求了,当然在创建类的时候就把List考虑进去,这样就可以统一在一个类中管理,即在类中嵌套List或者其他类,可以适应更复杂的业务场景,读者可以自行尝试一下。
有几点需要注意:
1. 如果没有注解的话,类中字段名字必须要和json字符串中对应的实体名保持一致,否则无法正常解析,因为Gson是根据java的反射原理进行数据映射的。
2. 通过添加注解的方式可以将类成员的名称与json字符串的实体不一致。只要在字段名添加@SerializedName("custom_naming")即可。例如@SerializedName("custom_naming")
private final String someField;
下面是官方文档上的一个示例:
private
class SomeObject {
@SerializedName("custom_naming") private final String someField;
private final String someOtherField;
public SomeObject(String a, String b) {
this.someField = a;
this.someOtherField = b;
}
}
SomeObject someObject = new SomeObject("first", "second");
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
String jsonRepresentation = gson.toJson(someObject);
System.out.println(jsonRepresentation);
======== OUTPUT ========
{"custom_naming":"first","SomeOtherField":"second"}
2. 如果类中的字段前加transient,那么在转换过程中Gson会忽略该字段,即不进行序列化和反序列化
3. 如果某个字段为空值,则转换后的json字符串将不包含该项;同理,如果json字符串不包含对象的某个字段,则转换后的对象该成员值为null。当然你也可以通过Gson
gson = new GsonBuilder().serializeNulls().create();来将空值显示为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;
}
}
Gson gson = new GsonBuilder().serializeNulls().create();
Foo foo = new Foo();
String json = gson.toJson(foo);
System.out.println(json);
json = gson.toJson(null);
System.out.println(json);
======== OUTPUT ========
{"s":null,"i":5}
null
好了,关于Gson的常用的用法都已经介绍完了,当然Gson还有一些其他的特性和用法,不是很常用就不介绍了,有兴趣的同学可以参看Gson的官方文档https://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Generic-Types。
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript(Standard
ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。
Android的SDK中包含四个与JSON相关的类和一个Exceptions:JSONArray、JSONObject、JSONStringer、JSONTokener、JSONException。通过这5个类我们就可以自行对Json进行解析。但是通过他们读写Json还都要停留到手工操作上,无法直接实现Json字符串到对象、对象到Json字符串的转换,例如解析Json需要通过Key值一个一个的取Value,工作量大不说,还增加了出错的几率。有没有办法可以:直接实现Json字符串到对象、对象到Json字符串的转换?
Gson是对成员变量field进行序列化,Android恰恰是推荐开发者直接使用成员变量访问而不是用setter、getter。Gson可以很容易地实现对象与json字符串之间的相互转换。因此本文着重介绍Gson的用法。
先来看一下官方文档对Gson的概述。Gson is a Java library that can be used to convert Java Objects into their JSON representation. It can also be used to convert
a JSON string to an equivalent Java object. Gson is an open-source project hosted at http://code.google.com/p/google-gson.这段话不复杂,想来大家都很容易理解,我就不过多解释了。
说了这么多如何使用呢?其实Gson用法很简单,但是却很强大。首先我们如果想要使用Gson就必须先创建一个Gson对象,有两种方式创建,一种是new Gson,一种是使用GsonBuilder来创建对象。官方文档的原话是这样的:The
primary class to use is Gson which
you can just create by calling new Gson(). There is also a class GsonBuilder available
that can be used to create a Gson instance with various settings like version control and so on. 创建的Gson对象可以通过单例模式一直使用。
接下来就是两个最主要的方法,toJson和fromJson。下面是官方文档提供的例子:
class
BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
(Serialization)
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson =
new Gson();
String json = gson.toJson(obj);
==>
json is {"value1":1,"value2":"abc"}
Note that you can not serialize objects with circular references since that will result in infinite recursion.
(Deserialization)
BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
是不是很方便。下面我总结了几种常用的转换关系:
1. 将json转换为对象
public static <T> T parseModel(String jsonStr, Class<T> cl) {
T obj = null;
if (gson != null) {
obj = gson.fromJson(jsonStr, cl);
}
return obj;
}
其中第二个参数只需要传Java类即可,例如MyClass.class
2. 将对象转换为json字符串
public static String objectToJson(Object ts) {
String jsonStr = null;
if (gson != null) {
jsonStr = gson.toJson(ts);
}
return jsonStr;
}
3. 将json字符串转换为List
public static <T> List<T> parseModelList(String jsonStr, com.google.gson.reflect.TypeToken<List<T>>
type) {
List<T> objList = null;
if (gson != null) {
objList = gson.fromJson(jsonStr, type.getType());
}
return objList;
}
4. 将List转换为json字符串
public static
String listToJson(List<?> list) {
String json = null;
if (gson != null) {
java.lang.reflect.Type type = new TypeToken<Map<?, ?>>() {}.getType();
json = gson.toJson(map, type);
}
returnjson;
}
5. 将json字符串转换为map
public static Map<?, ?> jsonToMap(String jsonStr) {
Map<?, ?> objMap = null;
if (gson != null) {
java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken<Map<?, ?>>() {
}.getType();
objMap = gson.fromJson(jsonStr, type);
}
return objMap;
}
6. 将map转换为json字符串
public staticString
mapToJson(Map<?, ?> map) {
String json = null;
if (gson != null) {
java.lang.reflect.Type type = new TypeToken<Map<?, ?>>() {}.getType();
json = gson.toJson(map, type);
}
return
json;
}
以上6中情况基本上可以满足正常的开发需求了,当然在创建类的时候就把List考虑进去,这样就可以统一在一个类中管理,即在类中嵌套List或者其他类,可以适应更复杂的业务场景,读者可以自行尝试一下。
有几点需要注意:
1. 如果没有注解的话,类中字段名字必须要和json字符串中对应的实体名保持一致,否则无法正常解析,因为Gson是根据java的反射原理进行数据映射的。
2. 通过添加注解的方式可以将类成员的名称与json字符串的实体不一致。只要在字段名添加@SerializedName("custom_naming")即可。例如@SerializedName("custom_naming")
private final String someField;
下面是官方文档上的一个示例:
private
class SomeObject {
@SerializedName("custom_naming") private final String someField;
private final String someOtherField;
public SomeObject(String a, String b) {
this.someField = a;
this.someOtherField = b;
}
}
SomeObject someObject = new SomeObject("first", "second");
Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
String jsonRepresentation = gson.toJson(someObject);
System.out.println(jsonRepresentation);
======== OUTPUT ========
{"custom_naming":"first","SomeOtherField":"second"}
2. 如果类中的字段前加transient,那么在转换过程中Gson会忽略该字段,即不进行序列化和反序列化
3. 如果某个字段为空值,则转换后的json字符串将不包含该项;同理,如果json字符串不包含对象的某个字段,则转换后的对象该成员值为null。当然你也可以通过Gson
gson = new GsonBuilder().serializeNulls().create();来将空值显示为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;
}
}
Gson gson = new GsonBuilder().serializeNulls().create();
Foo foo = new Foo();
String json = gson.toJson(foo);
System.out.println(json);
json = gson.toJson(null);
System.out.println(json);
======== OUTPUT ========
{"s":null,"i":5}
null
好了,关于Gson的常用的用法都已经介绍完了,当然Gson还有一些其他的特性和用法,不是很常用就不介绍了,有兴趣的同学可以参看Gson的官方文档https://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Generic-Types。
相关文章推荐
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- Android系统开关
- Android Data Binding语法解析(二)
- Android Data Binding语法解析(二)
- Android - Fragment(二)加载Fragment
- 使用Device Farm真机测试Android程序
- Android - Fragment (一)定义
- Android中ViewPager+Fragment的基本使用
- android listView滑动停止后加载图片
- Android Studio的使用
- [Android随笔]内存优化纪录篇
- 我是如何自学Android,资料分享
- 菜鸟学Android(四十四):jsp标签技术简介及jsp标签的开发详解
- android动画
- Android Api Demos登顶之路(二十一)Secure Surface
- Ubuntu下Android真机调试
- Android基础入门教程——2.3.7 ProgressBar(进度条)
- Android Service 与 Activity使用Pending Intent通信
- Android自定义View时添加自己的监听器
- Android之——激活应用程序的详情界面