Gson (GitHub:https://github.com/google/gson)是Google 提供的用來在Java 對象和JSON 數據之間進行映射的Java 類庫。可以將一個JSON 字符串轉成一個Java 對象,或者反過來。
Gson裡最重要的對像有2個Gson 和GsonBuilder。
Gson有2個最基本的方法(1)toJson() 轉換java 對像到JSON
(2)fromJson() 轉換JSON到java對象
編寫實體類:
public class People { String name; int age; boolean setName; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean getSetName() { return setName; } public void setSetName(boolean setName) { this.setName = setName; } @Override public String toString() { return "name=" + name + " age=" + age + " setName=" +setName; }}編寫測試類GsonTest
import com.google.gson.ExclusionStrategy;import com.google.gson.FieldAttributes;import com.google.gson.Gson;import com.google.gson.GsonBuilder;/** * Convert java object to json. */public class GsonTest { public static void main(String[] args) { People p = new People(); p.setAge(20); p.setName("People"); p.setSetName(true); Gson gson = new Gson(); System.out.println(gson.toJson(p)); }}輸出結果:
{"name":"People","age":20,"setName":true}這只是最簡單的Gson的使用。如果我們需要將bool類型的屬性setName在轉換成json的時候不轉換,怎麼實現呢?
在Gson的包中找半天,發現com.google.gson包下面有這麼一個接口:ExclusionStrategy ,雖然不清楚是乾什麼的,但是根據名字,可以推斷,這個接口是用來設置Gson轉換的排除策略的,於是在官網http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/index.html查了一下這個接口,發現只要實現這個接口,並將實現類的對象塞給Gson,在轉換成json的時候,Gson就會過濾掉指定的類或者屬性。於是有了下面的代碼:
import com.google.gson.ExclusionStrategy;import com.google.gson.FieldAttributes;import com.google.gson.Gson;import com.google.gson.GsonBuilder;/** * Convert java object to json, skip specific fileds. */public class GsonTest { public static void main(String[] args) { People p = new People(); p.setAge(20); p.setName("People"); p.setSetName(true); ExclusionStrategy excludeStrategy = new SetterExclusionStrategy(); Gson gson1 = new GsonBuilder() .setExclusionStrategies(excludeStrategy) .create(); Gson gson2 = new Gson(); String json1 = gson1.toJson(p); String json2 = gson2.toJson(p); System.out.println(json1); System.out.println(json2); People p1 = gson1.fromJson(json1, People.class); People p2 = gson2.fromJson(json2, People.class); System.out.println(p1); System.out.println(p2); } private static class SetterExclusionStrategy implements ExclusionStrategy { public boolean shouldSkipClass(Class<?> clazz) { return false; } public boolean shouldSkipField(FieldAttributes f) { return f.getName().startsWith("set"); } }}原來,Gson對象的創建有兩種方式:new Gson()表示使用默認的配置創建一個Gson對象,而如果使用GsonBuilder.create()方法創建,則可以自定義一些設置,這主要是為了使創建的Gson更適合於某些特定的情況。上例中第一段藍色的代碼創建了一個Gson對象,這個對象擁有對以“set”字樣開頭的屬性的過濾的配置(如果需要過濾掉某種類型,則重寫ExclusionStrategy接口的shouldSkipClass(Class<?> clazz)方法即可,如果需要過濾掉多種情況,則可以多創建幾個ExclusionStrategy的實現類對象,並在創建Gson對象的時候設置進去即可),因此在本例中,將People對象轉換成Json的時候,屬性setName將被過濾掉。由於json1中沒有屬性setName,所以將json1反序列化成People對象的時候,boolean類型的setName就沒有了值,所以打印的時候取了boolean類型的默認值。於是有了以下結果:
{"name":"People","age":20}{"name":"People","age":20,"setName":true}name=People age=20 setName=falsename=People age=20 setName=trueGson還支持使用註解,在com.google.gson.annotation包中,有幾個註解Expose, SerializedName, Since和Until,他們各有各的作用,下面使用官方例子介紹常用的註解:
Expose:
此註解作用在屬性上,表明當序列化和反序列化的時候,這個屬性將會暴露給Gson對象。這個註解只有當創建Gson對象時使用GsonBuilder方式創建並調用了GsonBuilder.excludeFieldsWithoutExposeAnnotation() 方法的時候才有效,否則無效。下面是一個介紹@Expose註解如何使用的例子:
public class User { @Expose private String firstName; @Expose(serialize = false) private String lastName; @Expose (serialize = false, deserialize = false) private String emailAddress; private String password;}如果你以new Gson()的方式創建Gson對象,toJson()方法和fromJson() 方法在序列化和反序列化的時候將會操作這4個屬性。然而,如果你使用Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create()來創建Gson對象,Gson 的toJson() 和fromJson() 方法將會排除掉password 字段,這是因為password 字段沒有被註解@Expose 所標記。 這個Gson 對象同樣會排除lastName 和emailAddress 字段,因為註解@Expose的屬性serialize 被設置成了false。類似的,Gson 將會在反序列化時排除掉emailAddress 字段,因為deserialize被設置成了false。
SerializedName:
此註解作用在屬性上,表明這個屬性在序列化成Json的時候,需要將名字序列化成註解的value屬性指定的值。
這個註解將會覆蓋任何的FieldNamingPolicy, 包括默認的命名策略。下面是一個介紹@SerializedName註解如何使用的例子: ,
public class SomeClassWithFields { @SerializedName("name") private final String someField; private final String someOtherField; public SomeClassWithFields(String a, String b) { this.someField = a; this.someOtherField = b; }}下面的代碼展示了序列化上面這個測試類的結果:
SomeClassWithFields objectToSerialize = new SomeClassWithFields("a", "b");Gson gson = new Gson();String jsonRepresentation = gson.toJson(objectToSerialize);System.out.println(jsonRepresentation);執行結果是:
{"name":"a","someOtherField":"b"}由此可見,屬性"someField"已經被序列化成了"name"。
注意:在@SerializedName的value中指定的屬性名必須為有效的Json屬性名。