天天看點

Json轉換神器之Google Gson的使用

這幾天,因為項目的需要,接觸了google的gson庫,發現這個東西很好用,遂記下簡單的筆記,供以後參考。至于gson是幹什麼的,有什麼優點,請各位同學自行百度。話不多說,切入正題:

1. 下載下傳gson的jar包,拷貝到項目的lib檔案夾中,并将其加入到buildpath中。使用maven的同學,直接在pom中加入以下依賴即可:

<a href="http://my.oschina.net/itblog/blog/204120#">?</a>

1

2

3

4

5

<code>&lt;</code><code>dependency</code><code>&gt;</code>

<code>  &lt;</code><code>groupid</code><code>&gt;com.google.code.gson&lt;/</code><code>groupid</code><code>&gt;</code>

<code>  &lt;</code><code>artifactid</code><code>&gt;gson&lt;/</code><code>artifactid</code><code>&gt;</code>

<code>  &lt;</code><code>version</code><code>&gt;2.2.4&lt;/</code><code>version</code><code>&gt;</code>

<code>&lt;/</code><code>dependency</code><code>&gt;</code>

2. 編寫實體類:

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

<code>public</code> <code>class</code> <code>people {</code>

<code>  string name;</code>

<code>  </code><code>int</code> <code>age;</code>

<code>  </code><code>boolean</code> <code>setname;</code>

<code>  </code><code>public</code> <code>string getname() {</code>

<code>    </code><code>return</code> <code>name;</code>

<code>  }</code>

<code>  </code><code>public</code> <code>void</code> <code>setname(string name) {</code>

<code>    </code><code>this</code><code>.name = name;</code>

<code>  </code><code>public</code> <code>int</code> <code>getage() {</code>

<code>    </code><code>return</code> <code>age;</code>

<code>  </code><code>public</code> <code>void</code> <code>setage(</code><code>int</code> <code>age) {</code>

<code>    </code><code>this</code><code>.age = age;</code>

<code>  </code><code>public</code> <code>boolean</code> <code>getsetname() {</code>

<code>    </code><code>return</code> <code>setname;</code>

<code>  </code><code>public</code> <code>void</code> <code>setsetname(</code><code>boolean</code> <code>setname) {</code>

<code>    </code><code>this</code><code>.setname = setname;</code>

<code>  </code><code>@override</code>

<code>  </code><code>public</code> <code>string tostring() {</code>

<code>    </code><code>return</code> <code>"name="</code> <code>+ name + </code><code>" age="</code> <code>+ age + </code><code>" setname="</code> <code>+setname;</code>

<code>}</code>

3. 編寫測試類gsontest

<code>import</code> <code>com.google.gson.exclusionstrategy;</code>

<code>import</code> <code>com.google.gson.fieldattributes;</code>

<code>import</code> <code>com.google.gson.gson;</code>

<code>import</code> <code>com.google.gson.gsonbuilder;</code>

<code>/**</code>

<code> </code><code>* convert java object to json.</code>

<code> </code><code>*/</code>

<code>public</code> <code>class</code> <code>gsontest {</code>

<code>  </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) {</code>

<code>    people p = </code><code>new</code> <code>people();</code>

<code>    p.setage(</code><code>20</code><code>);</code>

<code>    p.setname(</code><code>"people"</code><code>);</code>

<code>    p.setsetname(</code><code>true</code><code>);</code>

<code>    gson gson = </code><code>new</code> <code>gson();</code>

<code>    system.out.println(gson.tojson(p));</code>

4. 輸出結果:

<code>{</code><code>"name"</code><code>:</code><code>"people"</code><code>,</code><code>"age"</code><code>:</code><code>20</code><code>,</code><code>"setname"</code><code>:</code><code>true</code><code>}</code>

5. 這隻是最簡單的gson的使用。如果我們需要将bool類型的屬性setname在轉換成json的時候不轉換,怎麼實作呢? 

28

29

30

31

32

33

34

35

36

37

38

<code> * convert java object to json, skip specific fileds.</code>

<code> */</code>

<code>    exclusionstrategy excludestrategy = </code><code>new</code> <code>setterexclusionstrategy();</code>

<code>    gson gson1 = </code><code>new</code> <code>gsonbuilder()</code>

<code>      .setexclusionstrategies(excludestrategy)</code>

<code>      .create();</code>

<code>    gson gson2 = </code><code>new</code> <code>gson();</code>

<code>    string json1 = gson1.tojson(p);</code>

<code>    string json2 = gson2.tojson(p);</code>

<code>    system.out.println(json1);</code>

<code>    system.out.println(json2);</code>

<code>    people p1 = gson1.fromjson(json1, people.</code><code>class</code><code>);</code>

<code>    people p2 = gson2.fromjson(json2, people.</code><code>class</code><code>);</code>

<code>    system.out.println(p1);</code>

<code>    system.out.println(p2);</code>

<code>  </code><code>private</code> <code>static</code> <code>class</code> <code>setterexclusionstrategy </code><code>implements</code> <code>exclusionstrategy {</code>

<code>    </code><code>public</code> <code>boolean</code> <code>shouldskipclass(class&lt;?&gt; clazz) {</code>

<code>      </code><code>return</code> <code>false</code><code>;</code>

<code>    }</code>

<code>    </code><code>public</code> <code>boolean</code> <code>shouldskipfield(fieldattributes f) {</code>

<code>      </code><code>return</code> <code>f.getname().startswith(</code><code>"set"</code><code>);</code>

  原來,gson對象的建立有兩種方式:new gson()表示使用預設的配置建立一個gson對象,而如果使用gsonbuilder.create()方法建立,則可以自定義一些設定,這主要是為了使建立的gson更适合于某些特定的情況。上例中第一段藍色的代碼建立了一個gson對象,這個對象擁有對以“set”字樣開頭的屬性的過濾的配置(如果需要過濾掉某種類型,則重寫exclusionstrategy接口的shouldskipclass(class&lt;?&gt; clazz)方法即可,如果需要過濾掉多種情況,則可以多建立幾個exclusionstrategy的實作類對象,并在建立gson對象的時候設定進去即可),是以在本例中,将people對象轉換成json的時候,屬性setname将被過濾掉。由于json1中沒有屬性setname,是以将json1反序列化成people對象的時候,boolean類型的setname就沒有了值,是以列印的時候取了boolean類型的預設值。于是有了以下結果:

<code>{</code><code>"name"</code><code>:</code><code>"people"</code><code>,</code><code>"age"</code><code>:</code><code>20</code><code>}</code>

<code>name=people age=</code><code>20</code> <code>setname=</code><code>false</code>

<code>name=people age=</code><code>20</code> <code>setname=</code><code>true</code>

6. gson還支援使用注解,在com.google.gson.annotation包中,有幾個注解expose, serializedname, since和until,他們各有各的作用,下面使用官方例子介紹常用的注解: 

6.1 expose

<code>public</code> <code>class</code> <code>user {</code>

<code>   </code><code> </code><code>@expose</code> <code>private</code> <code>string firstname;</code>

<code>   </code><code> </code><code>@expose</code><code>(serialize = </code><code>false</code><code>) </code><code>private</code> <code>string lastname;</code>

<code>   </code><code> </code><code>@expose</code> <code>(serialize = </code><code>false</code><code>, deserialize = </code><code>false</code><code>) </code><code>private</code> <code>string emailaddress;</code>

<code>   </code><code> </code><code>private</code> <code>string password;</code>

      如果你以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。

6.2 serializedname

  此注解作用在屬性上,表明這個屬性在序列化成json的時候,需要将名字序列化成注解的value屬性指定的值。

<code>public</code> <code>class</code> <code>someclasswithfields {</code>

<code>   </code><code> </code><code>@serializedname</code><code>(</code><code>"name"</code><code>) </code><code>private</code> <code>final</code> <code>string somefield;</code>

<code>   </code><code> </code><code>private</code> <code>final</code> <code>string someotherfield;</code>

<code>   </code><code> </code><code>public</code> <code>someclasswithfields(string a, string b) {</code>

<code>     </code><code> </code><code>this</code><code>.somefield = a;</code>

<code>     </code><code> </code><code>this</code><code>.someotherfield = b;</code>

<code>   </code><code> }</code>

      下面的代碼展示了序列化上面這個測試類的結果:

<code>someclasswithfields objecttoserialize = </code><code>new</code> <code>someclasswithfields(</code><code>"a"</code><code>, </code><code>"b"</code><code>);</code>

<code>gson gson = </code><code>new</code> <code>gson();</code>

<code>string jsonrepresentation = gson.tojson(objecttoserialize);</code>

<code>system.out.println(jsonrepresentation);</code>

      執行結果是:

<code>===== output =====</code>

<code>{</code><code>"name"</code><code>:</code><code>"a"</code><code>,</code><code>"someotherfield"</code><code>:</code><code>"b"</code><code>}</code>

      由此可見,屬性"somefield"已經被序列化成了"name"。

  注意:在@serializedname的value中指定的屬性名必須為有效的json屬性名。

6.3 since和until相當,請同學們自行檢視官網的api文檔。