您的位置:首页 > 移动开发 > Android开发

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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: