Android json解析--GSON

     转载请注明出处:http://blog.csdn.net/duanyy1990/article/details/47303631

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScriptStandard 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。

猜你喜欢

转载自blog.csdn.net/duanyy1990/article/details/47303631