使用Gson解析JSON数据必须先在工程中添加依赖
compile 'com.google.code.gson:gson:2.6.2'
添加完之后,sync 之后,Android Studio会自动下载Gson的jar包
一、Gson的基本用法
在讲这个之前,我们先来了解一下Gson的几个类:
JsonElement
这是Json中元素的基类,它只提供了若干个类型判断的接口,简单判断这个Json元素的类型。以下几个类型都是它的子类。
1、JsonObject:包含多个JsonElement集合,每一个Json字符串的根节点都是一个JsonObject
{
“name”:“张三”,
“age”:“29”,
“grade”:{
“语文”:“88”,
“数学”:“98”
}
}
2、JsonArray:也表示JsonElement的集合,Json中的数组并不要求所有的数据类型都一样。
从集合角度来讲,JsonObject中的JsonElement是无序的,需通过键值对访问,而JsonArray中的集合元素是有序的,可通过下标访问
[“a”,“b”,true]
3、JsonPrimitive:这个比较有趣,可以将json数据中双引号解析出来
4、JsonNull:空,对应null
下面直接上代码:
Person.java
public class Person {
int age;
String name;
public Person() {
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
功能代码:
<span style="white-space:pre"> </span>// Gson实例化,这只是其中一种创建方式,另一种在下面会讲到
Gson gson = new Gson();
/* javabean(对象)转换json字符串 */
Person person1 = new Person(12,"张三");
String jsonStr1 = gson.toJson(person1);
Log.i("javabean转换json字符串 ---> ",jsonStr1);
/* json字符串转javabean(对象) */
String jsonStr2 = "{\"name\":\"李四\",\"age\":26}";
Person person2 = gson.fromJson(jsonStr2,Person.class);
Log.i("json字符串转javabea ---> ",person2.toString());
/* List Map 转json字符串 */
List<String> list = Arrays.asList("1", "a", "3", "rt", "5");
Log.i("List 转json字符串 ---> ",gson.toJson(list));
Map<String,Object> map = new HashMap<>();
map.put("name","张三");
map.put("age","26");
Log.i("Map 转json字符串 ---> ",gson.toJson(map));
/* json字符串转List */
String jsonStr3 = "[\"1\",\"a\",\"3\",\"rt\",\"5\"]";
Type type = new TypeToken<ArrayList<String>>(){}.getType();
ArrayList<String> slist = gson.fromJson(jsonStr3,type);
Log.i("json字符串转Lis ---> ",slist.toString());
/*
* JsonObject JsonArray
*/
// 创建JsonObject,通过addPropert(key,value)可以向jsonObject中添加字段,跟Map相似
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("name","张三");
jsonObject.addProperty("age","26");
Log.i("create JsonObject ---> ",jsonObject.getAsString());
// 创建JsonArray
JsonArray jsonArray = new JsonArray();
jsonArray.add("摄影");
jsonArray.add("爬山");
jsonArray.add("钓鱼");
Log.i("create JsonArray ---> ",jsonArray.getAsString());
// JsonObject中嵌套JsonArray
jsonObject.add("hobby",jsonArray);
Log.i("JsonArray in JsonObject",jsonObject.getAsString());
/*
* JsonPrimitive类可以获得json字符串中引号
*/
String jsonStr4 = "{\"name\":\"xuanyouwu\",\"age\":26}";
JsonPrimitive jsonPrimitive = new JsonPrimitive(jsonStr4);
Log.i("toString() ---> ",jsonPrimitive.toString());
Log.i("getAsString() ---> ",jsonPrimitive.getAsString());
二、Gson注解
有时候,我们不需要对json数据全部输出,或者要对其版本进行控制……这个时候就需要注解了。。
1、@Expose
区别实体中是否允许被序列化化,本身有两个属性deserialize(反序列化)和serialize(序列化),默认为true。如果将其设置为false的话,表示这一属性在(反)序列化的过程中不需要处理。实体中没有@Expose注解的属性在创建Gson对象时不会被序列化
其中有一点比较蛋疼的是,举个例子,当我们希望10个属性中,第5个属性不被序列化,一般思维是把第5个属性的注解去掉就行,但这行不通,我们需要将10个属性都加上注解,并将第5个的注解设置为false。
2、@SerializedName(重命名注解)
有时候,我们从服务器上获取的json数据,其key值必须跟我们实体中的字段名称相同,但如果服务器返回来的关键字,如int,switch这一些怎么办,我们在java中是不能定义这些字段的,或者服务器返回的字段太长…… 这个时候就得用SerializedName了。。
定义属性序列化后的名称,在序列化时,JsonElement的键值会被替换成这个名字;解析时,Json中键值为这个名字的JsonElement会赋值给被注解的属性。
<span style="white-space:pre"> </span>String name;
<span style="white-space:pre"> </span>int age;
<span style="white-space:pre"> </span>@SerializedName("new")
<span style="white-space:pre"> </span>int isnew;
结合alternate提供多种备用字段key来解析,@SerializedName(value=“desc”,alternate={“other”,“another”}),如果json中有other或another就会被解析成desc,所以value的值不能出现在alternate中,alternate是备选字段来的。
3、@Since和@Until
对实体(反)序列化时的版本控制,不小于Since的版本,不大于Until的版本,两个刚好是相反的意思。