日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Gson 解析教程

 甘甘灰 2018-08-03

Gson 是google解析Json的一個(gè)開源框架,同類的框架fastJson,JackJson等等

本人fastJson用了兩年,也是從去年才開始接觸Gson,希望下面的總結(jié)會(huì)對博友有用,至于Gson與FastJson的對比,其實(shí)半斤八兩的問題,不再贅述

第一步:在AS下面創(chuàng)建java工程 并添加gson依賴

compile 'com.google.code.gson:gson:2.6.2'



Gson的實(shí)例化方式:

1:Gson gson=newGson();

2:通過GsonBuilder 可以配置多種選項(xiàng)

  1. gson = new GsonBuilder()
  2. .setLenient()// json寬松
  3. .enableComplexMapKeySerialization()//支持Map的key為復(fù)雜對象的形式
  4. .serializeNulls() //智能null
  5. .setPrettyPrinting()// 調(diào)教格式
  6. .disableHtmlEscaping() //默認(rèn)是GSON把HTML 轉(zhuǎn)義的
  7. .create();
Gson的基本用法:

 JavaBean轉(zhuǎn)換Json字符串

 gson提供 publicString toJson(Object src) 方法可以將對象轉(zhuǎn)換成jsonStr

  

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. /**
  4. * @author xuanyouwu
  5. * @email xuanyouwu@163.com
  6. * @time 2016-05-18 10:39
  7. */
  8. public class GsonTest1 {
  9. public static class Student {
  10. private String name;
  11. private int age;
  12. //省略setter getter equals
  13. }
  14. private static void log(String msg) {
  15. System.out.println(msg);
  16. }
  17. public static void main(String[] args) throws Exception {
  18. Gson gson = new Gson();
  19. Student student = new Student();
  20. student.setName("xuanyouwu");
  21. student.setAge(26);
  22. String jsonStr = gson.toJson(student);
  23. log("---->javabean convert jsonStr:" + jsonStr);
  24. }
  25. }

運(yùn)行結(jié)果:

---->javabean convert jsonStr:{"name":"xuanyouwu","age":26}




    List Map轉(zhuǎn)Json字符串

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import java.util.Arrays;
  4. import java.util.HashMap;
  5. import java.util.List;
  6. import java.util.Map;
  7. /**
  8. * @author xuanyouwu
  9. * @email xuanyouwu@163.com
  10. * @time 2016-05-18 10:39
  11. */
  12. public class GsonTest1 {
  13. private static void log(String msg) {
  14. System.out.println(msg);
  15. }
  16. public static void main(String[] args) throws Exception {
  17. Gson gson = new Gson();
  18. List<String> list = Arrays.asList("1", "a", "3", "rt", "5");
  19. log("---->list convert jsonStr:" + gson.toJson(list));
  20. Map<String, Object> content = new HashMap<String, Object>();
  21. content.put("name", "xuanyouwu");
  22. content.put("age", "26");
  23. log("---->map convert jsonStr:" + gson.toJson(content));
  24. }
  25. }
運(yùn)行結(jié)果:
  1. ---->list convert jsonStr:["1","a","3","rt","5"]
  2. ---->map convert jsonStr:{"name":"xuanyouwu","age":"26"}

       Json字符串轉(zhuǎn)JavaBean

  1. String studentJsonStr="{\"name\":\"xuanyouwu\",\"age\":26}";
  2. Student student1 = gson.fromJson(studentJsonStr, Student.class);
  3. log("------->json convert JavaBean:"+student1);

      運(yùn)行結(jié)果:

            ------->json convert JavaBean:Student{name='xuanyouwu', age=26}



   Json字符串轉(zhuǎn)List

        String listJsonStr="[\"1\",\"a\",\"3\",\"rt\",\"5\"]";
  1. Type type = new TypeToken<ArrayList<String>>() {
  2. }.getType();
  3. ArrayList<String> sList=gson.fromJson(listJsonStr, type);
  4. log("------->json convert List:"+sList);
    運(yùn)行結(jié)果:
        ------->json convert List:[1, a, 3, rt, 5]
</pre><pre code_snippet_id="1687762" snippet_file_name="blog_20160518_11_939636" name="code" class="java">  Gson封裝的類型體系
    Gson里面有一個(gè)非常有意思的抽象基類JsonElement,他的繼承體系:
    <img src="https://img-blog.csdn.net/20160518135136864?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
 JsonObject等同于org的JSONObject,JsonArray也類似,
   JsonNull 其實(shí)就是null 字段
     JsonNull jsonNull=new JsonNull();//構(gòu)造方法過時(shí),推薦INSTANCE


  1. JsonNull jsonNull=JsonNull.INSTANCE;
  2. log("-----"+jsonNull);
   運(yùn)行結(jié)果:
      -----null

     JsonPrimitive非常有意思,我們知道如果json轉(zhuǎn)換成字符串 可能包含引號(hào)的轉(zhuǎn)義,但是通過JsonPrimative我們可以獲得為轉(zhuǎn)義的字符串,看實(shí)例:

     

  1. package com.xuan.gson;
  2. import com.google.gson.JsonNull;
  3. import com.google.gson.JsonPrimitive;
  4. /**
  5. * @author xuanyouwu
  6. * @email xuanyouwu@163.com
  7. * @time 2016-05-18 11:20
  8. */
  9. public class GsonTest2 {
  10. private static void log(String msg) {
  11. System.out.println(msg);
  12. }
  13. public static void main(String[] args) throws Exception {
  14. String studentJsonStr="{\"name\":\"xuanyouwu\",\"age\":26}";
  15. log("------>studentJsonStr:"+studentJsonStr);
  16. JsonPrimitive jsonPrimitive=new JsonPrimitive(studentJsonStr);
  17. log("------>jsonPrimitive:"+jsonPrimitive);
  18. log("------>jsonPrimitive:"+jsonPrimitive.toString());
  19. log("------>jsonPrimitive:"+jsonPrimitive.getAsString());
  20. JsonPrimitive jsonPrimitive2=new JsonPrimitive("this is String");
  21. log("------>jsonPrimitive2:"+jsonPrimitive2);
  22. log("------>jsonPrimitive2:"+jsonPrimitive2.toString());
  23. log("------>jsonPrimitive2:"+jsonPrimitive2.getAsString());
  24. }
  25. }

     運(yùn)行結(jié)果:

------>studentJsonStr:{"name":"xuanyouwu","age":26}
------>jsonPrimitive:"{\"name\":\"xuanyouwu\",\"age\":26}"
------>jsonPrimitive:"{\"name\":\"xuanyouwu\",\"age\":26}"
------>jsonPrimitive:{"name":"xuanyouwu","age":26}
------>jsonPrimitive2:"this is String"
------>jsonPrimitive2:"this is String"
------>jsonPrimitive2:this is String




       創(chuàng)建JsonObject

           通過addPropert(key,value)可以向jsonObject中添加字段 跟hashMap類似

  1. JsonObject jsonObject=new JsonObject();
  2. jsonObject.addProperty("name","xuanyouwu");
  3. jsonObject.addProperty("age",26);
  4. log("------>create jsonObject:"+jsonObject);
            運(yùn)行結(jié)果:

                ------>create jsonObject:{"name":"xuanyouwu","age":26}



    創(chuàng)建JsonArray       

  1. JsonArray jsonElements=new JsonArray();
  2. jsonElements.add("a");
  3. jsonElements.add("b");
  4. jsonElements.add("c");
  5. jsonElements.add("d");
  6. log("------>create jsonArray:"+jsonElements);
          運(yùn)行結(jié)果:

          ------>create jsonArray:["a","b","c","d"]



     JsonObject 嵌套數(shù)組或者說嵌套JsonArray

           通過JsonObject的add(key,JsonElement)可以為jsonObject 添加一個(gè)數(shù)組的字段

  1. JsonObject jsonObject2=new JsonObject();
  2. jsonObject2.addProperty("name","xuanyouwu");
  3. jsonObject2.addProperty("age",26);
  4. JsonArray jsonElements2=new JsonArray();
  5. jsonElements2.add("騎車");
  6. jsonElements2.add("打游戲");
  7. jsonElements2.add("看電視");
  8. jsonObject2.add("hobby",jsonElements2);
  9. log("------>create jsonObject inner JsonArray:"+jsonObject2);
           運(yùn)行結(jié)果:

            ------>create jsonObject inner JsonArray:{"name":"xuanyouwu","age":26,"hobby":["騎車","打游戲","看電視"]}




Gson注解

          在Gson中有五類注解

          




          重命名注解:SerializedName 

             作用:轉(zhuǎn)換關(guān)鍵字key,json轉(zhuǎn)換成JavaBean時(shí),json字段的key 默認(rèn)必須和我們聲明類的字段名稱一樣,當(dāng)服務(wù)器端返回了關(guān)鍵字怎么辦,比如key 為new switch這樣,我們    在聲明類的時(shí)候不能寫這樣的字段,可能你想服務(wù)器端改動(dòng),他可能要改數(shù)據(jù)庫,但是我告訴你,做服務(wù)端的大部分不愿意改動(dòng)他的json,是很自私的!這時(shí)候重命名注解都排上用場了   第二種場景:服務(wù)器端返回的json 的key 簡直太丑,或者太長,你想簡化,my_parent_name,可以簡化成mpn 比較優(yōu)雅簡介

          實(shí)例:

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.annotations.SerializedName;
  4. /**
  5. * @author xuanyouwu
  6. * @email xuanyouwu@163.com
  7. * @time 2016-05-18 11:20
  8. */
  9. public class GsonTest3 {
  10. private static void log(String msg) {
  11. System.out.println(msg);
  12. }
  13. public static class User {
  14. public String name;
  15. public int age;
  16. @SerializedName("new")
  17. public int isnew;
  18. @Override
  19. public String toString() {
  20. return "User{" +
  21. "name='" + name + '\'' +
  22. ", age=" + age +
  23. ", isnew=" + isnew +
  24. '}';
  25. }
  26. }
  27. public static void main(String[] args) throws Exception {
  28. String jsonFromServer = "{\n" +
  29. " \"age\": 26,\n" +
  30. " \"name\": \"zhangsan\",\n" +
  31. " \"new\": 1\n" +
  32. "}";
  33. Gson gson = new Gson();
  34. User user = gson.fromJson(jsonFromServer, User.class);
  35. log("------>user:" + user);
  36. }
  37. }

運(yùn)行結(jié)果: ------>user:User{name='zhangsan', age=26, isnew=1}


  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.annotations.SerializedName;
  4. /**
  5. * @author xuanyouwu
  6. * @email xuanyouwu@163.com
  7. * @time 2016-05-18 11:20
  8. */
  9. public class GsonTest3 {
  10. private static void log(String msg) {
  11. System.out.println(msg);
  12. }
  13. public static class User2 {
  14. public String name;
  15. public int age;
  16. @SerializedName("my_parent_name")
  17. public String pn;
  18. @Override
  19. public String toString() {
  20. return "User2{" +
  21. "name='" + name + '\'' +
  22. ", age=" + age +
  23. ", pn='" + pn + '\'' +
  24. '}';
  25. }
  26. }
  27. public static void main(String[] args) throws Exception {
  28. String jsonFromServer2="{\n" +
  29. " \"age\": 26,\n" +
  30. " \"my_parent_name\": \"zhangsanf\",\n" +
  31. " \"name\": \"zhangsan\"\n" +
  32. "}";
  33. Gson gson2 = new Gson();
  34. User2 user2 = gson2.fromJson(jsonFromServer2, User2.class);
  35. log("------>user2:" + user2);
  36. }
  37. }

運(yùn)行結(jié)果: ------>user2:User2{name='zhangsan', age=26, pn='zhangsanf'}


        作用2:結(jié)合alternate 提供多種備用字段key來解析,@SerializedName(value ="desc",alternate = {"other","note"})  如果json中有other就會(huì)解析成desc 如果有note也會(huì)解析成desc,注意1:value中的值不能出現(xiàn)在alternate中,注意2:alternate的備選字段 會(huì)后面的替換前面的

   實(shí)例:

   

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.annotations.SerializedName;
  4. /**
  5. * @author xuanyouwu
  6. * @email xuanyouwu@163.com
  7. * @time 2016-05-18 11:20
  8. */
  9. public class GsonTest4 {
  10. private static void log(String msg) {
  11. System.out.println(msg);
  12. }
  13. public static class User {
  14. public String name;
  15. public int age;
  16. @SerializedName(value = "desc",alternate = {"other","note"})
  17. public String desc;
  18. @Override
  19. public String toString() {
  20. return "User{" +
  21. "name='" + name + '\'' +
  22. ", age=" + age +
  23. ", desc='" + desc + '\'' +
  24. '}';
  25. }
  26. }
  27. public static void main(String[] args) throws Exception {
  28. String jsonFromServer = "{\n" +
  29. " \"age\": 26,\n" +
  30. " \"other\": \"成都人\",\n" +
  31. " \"name\": \"zhangsan\"\n" +
  32. "}";
  33. Gson gson = new Gson();
  34. User user = gson.fromJson(jsonFromServer, User.class);
  35. log("------>user:" + user);
  36. String jsonFromServer2 = "{\n" +
  37. " \"age\": 26,\n" +
  38. " \"note\": \"成都人\",\n" +
  39. " \"name\": \"zhangsan\"\n" +
  40. "}";
  41. User user2 = gson.fromJson(jsonFromServer2, User.class);
  42. log("------>user:" + user2);
  43. //包括desc 與note note在desc之后
  44. String jsonFromServer3="{\n" +
  45. " \"age\": 26,\n" +
  46. " \"desc\": \"desc成都人\",\n" +
  47. " \"name\": \"zhangsan\",\n" +
  48. " \"note\": \"note成都人\"\n" +
  49. "}";
  50. User user3 = gson.fromJson(jsonFromServer3, User.class);
  51. log("------>user:" + user3);
  52. //包括desc 與note note在desc之前
  53. String jsonFromServer4="{\n" +
  54. " \"age\": 26,\n" +
  55. " \"note\": \"note成都人\",\n" +
  56. " \"name\": \"zhangsan\",\n" +
  57. " \"desc\": \"desc成都人\"\n" +
  58. "}";
  59. User user4 = gson.fromJson(jsonFromServer4, User.class);
  60. log("------>user:" + user4);
  61. }
  62. }
  運(yùn)行結(jié)果:

     ------>user:User{name='zhangsan', age=26, desc='成都人'}
------>user:User{name='zhangsan', age=26, desc='成都人'}
------>user:User{name='zhangsan', age=26, desc='note成都人'}
------>user:User{name='zhangsan', age=26, desc='desc成都人'}



  Gson @Expose過濾注解 

  源碼:默認(rèn)既可以序列化又可以反序列化

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target(ElementType.FIELD)
  3. public @interface Expose {
  4. public boolean serialize() default true;
  5. public boolean deserialize() default true;
  6. }
</pre><pre code_snippet_id="1687762" snippet_file_name="blog_20160518_25_4965554" name="code" class="java">可以排除不需要序列化的字段,需要配合GsonBuilder使用
  1. <pre style="font-family: 宋體; font-size: 9pt; background-color: rgb(255, 255, 255);"><pre name="code" class="java"> Gson gson = new GsonBuilder()
  2. .excludeFieldsWithoutExposeAnnotation()
  3. .create();



  不添加@Expose注解的字段將不會(huì)解析:
   分為以下幾種情況:
    1:不添加@Expose注解等同于@Expose(deserialize = false,serialize = false) 不做任何解析
    2:@Expose(deserialize = true,serialize = false) 只解析用用,也就是反序列化可以,序列化不可以
    3:@Expose(deserialize = false,serialize = true) 序列化可以,反序列化不行
    4:@Expose(deserialize = true,serialize = true) 既可以序列化,也可以反序列化
    實(shí)例:將分別演示這四種情況



  不添加@Expose注解:等同于@Expose(deserialize = false,serialize = false)
  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.GsonBuilder;
  4. /**
  5. * @author xuanyouwu
  6. * @email xuanyouwu@163.com
  7. * @time 2016-05-18 11:20
  8. */
  9. public class GsonTest5 {
  10. private static void log(String msg) {
  11. System.out.println(msg);
  12. }
  13. public static class User {
  14. public String name;
  15. @Override
  16. public String toString() {
  17. return "User{" +
  18. "name='" + name + '\'' +
  19. '}';
  20. }
  21. }
  22. public static void main(String[] args) throws Exception {
  23. String jsonFromServer = "{\"name\": \"zhangsan\"}";
  24. Gson gson = new GsonBuilder()
  25. .excludeFieldsWithoutExposeAnnotation()
  26. .create();
  27. User user = gson.fromJson(jsonFromServer, User.class);
  28. log("------>反序列化:" + user);
  29. User user1 = new User();
  30. user1.name = "zhangsan2";
  31. String userStr = gson.toJson(user1);
  32. log("------>序列化:" + userStr);
  33. }
  34. }

運(yùn)行結(jié)果:
------>反序列化:User{name='null'}
------>序列化:{}





  添加@Expose注解 
  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.GsonBuilder;
  4. import com.google.gson.annotations.Expose;
  5. /**
  6. * @author xuanyouwu
  7. * @email xuanyouwu@163.com
  8. * @time 2016-05-18 11:20
  9. */
  10. public class GsonTest5 {
  11. private static void log(String msg) {
  12. System.out.println(msg);
  13. }
  14. public static class User {
  15. @Expose //等同于 @Expose(deserialize = true,serialize = true)
  16. public String name;
  17. @Override
  18. public String toString() {
  19. return "User{" +
  20. "name='" + name + '\'' +
  21. '}';
  22. }
  23. }
  24. public static void main(String[] args) throws Exception {
  25. String jsonFromServer = "{\"name\": \"zhangsan\"}";
  26. Gson gson = new GsonBuilder()
  27. .excludeFieldsWithoutExposeAnnotation()
  28. .create();
  29. User user = gson.fromJson(jsonFromServer, User.class);
  30. log("------>反序列化:" + user);
  31. User user1 = new User();
  32. user1.name = "zhangsan2";
  33. String userStr = gson.toJson(user1);
  34. log("------>序列化:" + userStr);
  35. }
  36. }

運(yùn)行結(jié)果:

------>反序列化:User{name='zhangsan'}
------>序列化:{"name":"zhangsan2"}



@Expose注解 只序列化

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.GsonBuilder;
  4. import com.google.gson.annotations.Expose;
  5. /**
  6. * @author xuanyouwu
  7. * @email xuanyouwu@163.com
  8. * @time 2016-05-18 11:20
  9. */
  10. public class GsonTest5 {
  11. private static void log(String msg) {
  12. System.out.println(msg);
  13. }
  14. public static class User {
  15. @Expose(deserialize = false,serialize = true)
  16. public String name;
  17. @Override
  18. public String toString() {
  19. return "User{" +
  20. "name='" + name + '\'' +
  21. '}';
  22. }
  23. }
  24. public static void main(String[] args) throws Exception {
  25. String jsonFromServer = "{\"name\": \"zhangsan\"}";
  26. Gson gson = new GsonBuilder()
  27. .excludeFieldsWithoutExposeAnnotation()
  28. .create();
  29. User user = gson.fromJson(jsonFromServer, User.class);
  30. log("------>反序列化:" + user);
  31. User user1 = new User();
  32. user1.name = "zhangsan2";
  33. String userStr = gson.toJson(user1);
  34. log("------>序列化:" + userStr);
  35. }
  36. }


運(yùn)行結(jié)果:

------>反序列化:User{name='null'}------>序列化:{"name":"zhangsan2"}

      @Expose 只反序列化

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.GsonBuilder;
  4. import com.google.gson.annotations.Expose;
  5. /**
  6. * @author xuanyouwu
  7. * @email xuanyouwu@163.com
  8. * @time 2016-05-18 11:20
  9. */
  10. public class GsonTest5 {
  11. private static void log(String msg) {
  12. System.out.println(msg);
  13. }
  14. public static class User {
  15. @Expose(deserialize = true, serialize = false)
  16. public String name;
  17. @Override
  18. public String toString() {
  19. return "User{" +
  20. "name='" + name + '\'' +
  21. '}';
  22. }
  23. }
  24. public static void main(String[] args) throws Exception {
  25. String jsonFromServer = "{\"name\": \"zhangsan\"}";
  26. Gson gson = new GsonBuilder()
  27. .excludeFieldsWithoutExposeAnnotation()
  28. .create();
  29. User user = gson.fromJson(jsonFromServer, User.class);
  30. log("------>反序列化:" + user);
  31. User user1 = new User();
  32. user1.name = "zhangsan2";
  33. String userStr = gson.toJson(user1);
  34. log("------>序列化:" + userStr);
  35. }
  36. }

運(yùn)行結(jié)果:

 ------>反序列化:User{name='zhangsan'}
------>序列化:{}



    @Since(float v)注解  版本控制 

      結(jié)合GsonBuilder.setVersion(n)使用 當(dāng)n>=v時(shí) 才會(huì)序列化解析

 

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.GsonBuilder;
  4. import com.google.gson.annotations.Since;
  5. /**
  6. * @author xuanyouwu
  7. * @email xuanyouwu@163.com
  8. * @time 2016-05-18 11:20
  9. */
  10. public class GsonTest6 {
  11. private static void log(String msg) {
  12. System.out.println(msg);
  13. }
  14. public static class User {
  15. @Since(2)
  16. public String name;
  17. @Override
  18. public String toString() {
  19. return "User{" +
  20. "name='" + name + '\'' +
  21. '}';
  22. }
  23. }
  24. public static void main(String[] args) throws Exception {
  25. String jsonFromServer = "{\"name\": \"zhangsan\"}";
  26. Gson gson = new GsonBuilder()
  27. .setVersion(1)//版本為1
  28. .create();
  29. User user1 = gson.fromJson(jsonFromServer, User.class);
  30. log("------>反序列化v=1:" + user1);
  31. User user1_1 = new User();
  32. user1_1.name = "zhangsan2";
  33. String userStr = gson.toJson(user1_1);
  34. log("------>序列化v=1:" + userStr);
  35. Gson gson2 = new GsonBuilder()
  36. .setVersion(2)//版本為2
  37. .create();
  38. User user2 = gson2.fromJson(jsonFromServer, User.class);
  39. log("------>反序列化v=2:" + user2);
  40. User user2_1 = new User();
  41. user2_1.name = "zhangsan2";
  42. String userStr2_1 = gson2.toJson(user2_1);
  43. log("------>序列化v=2:" + userStr2_1);
  44. Gson gson3 = new GsonBuilder()
  45. .setVersion(3)//版本為3
  46. .create();
  47. User user3 = gson3.fromJson(jsonFromServer, User.class);
  48. log("------>反序列化v=3:" + user3);
  49. User user3_1 = new User();
  50. user3_1.name = "zhangsan2";
  51. String userStr3_1 = gson3.toJson(user3_1);
  52. log("------>序列化v=3:" + userStr3_1);
  53. }
  54. }

運(yùn)行結(jié)果:

------>反序列化v=1:User{name='null'}
------>序列化v=1:{}
------>反序列化v=2:User{name='zhangsan'}
------>序列化v=2:{"name":"zhangsan2"}
------>反序列化v=3:User{name='zhangsan'}
------>序列化v=3:{"name":"zhangsan2"}



    @Util(float v)注解 版本控制

      當(dāng)gson的setVersion(n) n<v 才解析

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.GsonBuilder;
  4. import com.google.gson.annotations.Until;
  5. /**
  6. * @author xuanyouwu
  7. * @email xuanyouwu@163.com
  8. * @time 2016-05-18 11:20
  9. */
  10. public class GsonTest6 {
  11. private static void log(String msg) {
  12. System.out.println(msg);
  13. }
  14. public static class User {
  15. @Until(2)
  16. public String name;
  17. @Override
  18. public String toString() {
  19. return "User{" +
  20. "name='" + name + '\'' +
  21. '}';
  22. }
  23. }
  24. public static void main(String[] args) throws Exception {
  25. String jsonFromServer = "{\"name\": \"zhangsan\"}";
  26. Gson gson = new GsonBuilder()
  27. .setVersion(1)//版本為1
  28. .create();
  29. User user1 = gson.fromJson(jsonFromServer, User.class);
  30. log("------>反序列化v=1:" + user1);
  31. User user1_1 = new User();
  32. user1_1.name = "zhangsan2";
  33. String userStr = gson.toJson(user1_1);
  34. log("------>序列化v=1:" + userStr);
  35. Gson gson2 = new GsonBuilder()
  36. .setVersion(2)//版本為2
  37. .create();
  38. User user2 = gson2.fromJson(jsonFromServer, User.class);
  39. log("------>反序列化v=2:" + user2);
  40. User user2_1 = new User();
  41. user2_1.name = "zhangsan2";
  42. String userStr2_1 = gson2.toJson(user2_1);
  43. log("------>序列化v=2:" + userStr2_1);
  44. Gson gson3 = new GsonBuilder()
  45. .setVersion(3)//版本為3
  46. .create();
  47. User user3 = gson3.fromJson(jsonFromServer, User.class);
  48. log("------>反序列化v=3:" + user3);
  49. User user3_1 = new User();
  50. user3_1.name = "zhangsan2";
  51. String userStr3_1 = gson3.toJson(user3_1);
  52. log("------>序列化v=3:" + userStr3_1);
  53. }
  54. }

運(yùn)行結(jié)果:

------>反序列化v=1:User{name='zhangsan'}
------>序列化v=1:{"name":"zhangsan2"}
------>反序列化v=2:User{name='null'}
------>序列化v=2:{}
------>反序列化v=3:User{name='null'}
------>序列化v=3:{}


Gson 高級(jí)用法

    相信看過retrofit2.0 源碼的同學(xué)都知道,其中有一個(gè)GsonConverterFactory 里面的用法十分精煉老成,這里來一段源碼

 



   據(jù)說使用TypeAdapter 效率更高,本人還未對比測試,暫時(shí)放后吧,TypeAdapter是什么玩意呢?

   在源碼中備注了一句 Converts Java objects to and from JSON 就是對象json之間的互相轉(zhuǎn)換 接替了T 泛型類的序列化和反序列化的邏輯

   從源碼中我們看到區(qū)分了2.1版本之前后之后的用法,2.1版本之前可以自定義adapter:

   

  1. public class PointAdapter extends TypeAdapter<Point> {
  2. * public Point read(JsonReader reader) throws IOException {
  3. * if (reader.peek() == JsonToken.NULL) {
  4. * reader.nextNull();
  5. * return null;
  6. * }
  7. * String xy = reader.nextString();
  8. * String[] parts = xy.split(",");
  9. * int x = Integer.parseInt(parts[0]);
  10. * int y = Integer.parseInt(parts[1]);
  11. * return new Point(x, y);
  12. * }
  13. * public void write(JsonWriter writer, Point value) throws IOException {
  14. * if (value == null) {
  15. * writer.nullValue();
  16. * return;
  17. * }
  18. * String xy = value.getX() + "," + value.getY();
  19. * writer.value(xy);
  20. * }
  21. * }}

    使用

  

  1. GsonBuilder builder = new GsonBuilder();
  2. * builder.registerTypeAdapter(Point.class, new PointAdapter());
  3. * // if PointAdapter didn't check for nulls in its read/write methods, you should instead use
  4. * // builder.registerTypeAdapter(Point.class, new PointAdapter().nullSafe());
  5. * ...
  6. * Gson gson = builder.create();

    在2.1版本之后更推薦直接插入泛型就使用

  1. // String json = "{'origin':'0,0','points':['1,2','3,4']}";
  2. // TypeAdapter<Graph> graphAdapter = gson.getAdapter(Graph.class);
  3. // Graph graph = graphAdapter.fromJson(json);
  4. // }</pre>
  5. // And an example for serialization: <pre> {@code
  6. //
  7. // Graph graph = new Graph(...);
  8. // TypeAdapter<Graph> graphAdapter = gson.getAdapter(Graph.class);
  9. // String json = graphAdapter.toJson(graph);
  10. // }</pre>

   實(shí)例:使用TypeAdapter 來序列化和反序列化
   
  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.TypeAdapter;
  4. /**
  5. * @author xuanyouwu
  6. * @email xuanyouwu@163.com
  7. * @time 2016-05-18 11:20
  8. */
  9. public class GsonTest7 {
  10. private static void log(String msg) {
  11. System.out.println(msg);
  12. }
  13. public static class User {
  14. public String name;
  15. public int age;
  16. @Override
  17. public String toString() {
  18. return "User{" +
  19. "name='" + name + '\'' +
  20. ", age=" + age +
  21. '}';
  22. }
  23. }
  24. public static void main(String[] args) throws Exception {
  25. Gson gson = new Gson();
  26. TypeAdapter<User> userTypeAdapter = gson.getAdapter(User.class);
  27. User user = new User();
  28. user.name = "xuanyouwu";
  29. user.age = 26;
  30. String userJsonStr = userTypeAdapter.toJson(user);
  31. log("------>序列化:" + userJsonStr);
  32. User user1 = userTypeAdapter.fromJson(userJsonStr);
  33. log("------>反序列化:" + user1);
  34. }
  35. }
運(yùn)行結(jié)果:
  1. ------>序列化:{"name":"xuanyouwu","age":26}
  2. ------>反序列化:User{name='xuanyouwu', age=26}

Gson的容錯(cuò)機(jī)制:
   為什么要容錯(cuò)了,在javaBean中聲明了int類型的age 如果服務(wù)端 返回的是"" 空字符串怎么辦呢?崩潰?
   如果json格式不規(guī)范如 {name=zhangsan,age:26,hobby=null}  發(fā)現(xiàn)不是普通的key value
  容錯(cuò)實(shí)現(xiàn)方式1:
  1:創(chuàng)建Gson的方式
  1. gson = new GsonBuilder()
  2. .setLenient()// json寬松
  3. .create();
2:使用JsonReader
   JsonReader jsonReader = gson.newJsonReader(value.charStream());
   jsonReader.<span style="font-family: 宋體; font-size: 9pt;">setLenient(true)</span>

    3:自定義TypeAdapter

    4:使用注解JsonAdapter,其實(shí)也是自定義Adapter

 

 1.2歸為一類 由框架實(shí)現(xiàn),基本json大格式規(guī)范,鍵值對不標(biāo)準(zhǔn),多引號(hào)的問題等等,而不報(bào)錯(cuò)停止解析,但是功能相對較弱

 能解決bug 

com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON 

3,4歸為一類,都屬于自定義adapter,但是3與gson綁定,4使用注解和字段綁定

 實(shí)例:

   

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.GsonBuilder;
  4. import com.google.gson.JsonParseException;
  5. import com.google.gson.TypeAdapter;
  6. import com.google.gson.stream.JsonReader;
  7. import com.google.gson.stream.JsonWriter;
  8. import java.io.IOException;
  9. /**
  10. * @author xuanyouwu
  11. * @email xuanyouwu@163.com
  12. * @time 2016-05-18 11:20
  13. */
  14. public class GsonTest8 {
  15. private static void log(String msg) {
  16. System.out.println(msg);
  17. }
  18. public static class User {
  19. public String name;
  20. public int age;
  21. @Override
  22. public String toString() {
  23. return "User{" +
  24. "name='" + name + '\'' +
  25. ", age=" + age +
  26. '}';
  27. }
  28. ;
  29. }
  30. public static class UserTypeAdapter extends TypeAdapter<User> {
  31. @Override
  32. public void write(JsonWriter out, User value) throws IOException {
  33. out.beginObject();
  34. out.name("name").value(value.name);
  35. out.name("age").value(value.age);
  36. out.endObject();
  37. }
  38. @Override
  39. public User read(JsonReader in) throws IOException {
  40. User user = new User();
  41. in.beginObject();
  42. while (in.hasNext()) {
  43. switch (in.nextName()) {
  44. case "name":
  45. user.name = in.nextString();
  46. break;
  47. case "age":
  48. try {
  49. String str = in.nextString();
  50. user.age = Integer.valueOf(str);
  51. } catch (Exception e) {
  52. }
  53. break;
  54. }
  55. }
  56. in.endObject();
  57. return user;
  58. }
  59. }
  60. public static void main(String[] args) throws Exception {
  61. Gson gson = new Gson();
  62. String jsonStrFromServer = "{\n" +
  63. " \"age\": \"\",\n" +
  64. " \"name\": \"zhangsan\"\n" +
  65. "}";
  66. log("------->jsonFromServer:"+jsonStrFromServer);
  67. try {
  68. User user = gson.fromJson(jsonStrFromServer, User.class);
  69. log("------>默認(rèn)Gson 解析:" + user);
  70. } catch (JsonParseException e) {//java.lang.NumberFormatException: empty String
  71. log("------>默認(rèn)Gson 解析 異常:" + e);
  72. }
  73. Gson gson2 = new GsonBuilder()
  74. .registerTypeAdapter(User.class, new UserTypeAdapter()).create();
  75. try {
  76. User user2 = gson2.fromJson(jsonStrFromServer, User.class);
  77. log("------>自定義adapter 解析:" + user2);
  78. } catch (JsonParseException e) {//java.lang.NumberFormatException: empty String
  79. log("------>自定義adapter 異常:" + e);
  80. }
  81. try {
  82. UserTypeAdapter userTypeAdapter = new UserTypeAdapter();
  83. User user3 = userTypeAdapter.fromJson(jsonStrFromServer);
  84. log("------>自定義adapter 解析2:" + user3);
  85. } catch (Exception e) {
  86. log("------>自定義adapter 異常2:" + e);
  87. }
  88. }
  89. }

運(yùn)行結(jié)果:

------->jsonFromServer:{
    "age": "",
    "name": "zhangsan"
}
------>默認(rèn)Gson 解析 異常:com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String
------>自定義adapter 解析:User{name='zhangsan', age=0}
------>自定義adapter 解析2:User{name='zhangsan', age=0}

可以看到 age是空字符串 但是不影響整體的解析流程,這對客戶端是十分友好的


  基于注解的方式,上面的方式傾向于整體,注解的方式傾向于字段

  

  1. package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.JsonParseException;
  4. import com.google.gson.TypeAdapter;
  5. import com.google.gson.annotations.JsonAdapter;
  6. import com.google.gson.stream.JsonReader;
  7. import com.google.gson.stream.JsonWriter;
  8. import java.io.IOException;
  9. /**
  10. * @author xuanyouwu
  11. * @email xuanyouwu@163.com
  12. * @time 2016-05-18 11:20
  13. */
  14. public class GsonTest9 {
  15. private static void log(String msg) {
  16. System.out.println(msg);
  17. }
  18. public static class User {
  19. public String name;
  20. @JsonAdapter(IntegerTypeAdapter.class)
  21. public int age;
  22. @Override
  23. public String toString() {
  24. return "User{" +
  25. "name='" + name + '\'' +
  26. ", age=" + age +
  27. '}';
  28. }
  29. }
  30. public static class IntegerTypeAdapter extends TypeAdapter<Integer> {
  31. @Override
  32. public void write(JsonWriter out, Integer value) throws IOException {
  33. out.value(value);
  34. }
  35. @Override
  36. public Integer read(JsonReader in) throws IOException {
  37. int i = 0;
  38. try {
  39. String str = in.nextString();
  40. i = Integer.valueOf(str);
  41. } catch (Exception e) {
  42. }
  43. return i;
  44. }
  45. }
  46. public static class User2 {
  47. public String name;
  48. public int age;
  49. @Override
  50. public String toString() {
  51. return "User{" +
  52. "name='" + name + '\'' +
  53. ", age=" + age +
  54. '}';
  55. }
  56. }
  57. public static void main(String[] args) throws Exception {
  58. Gson gson = new Gson();
  59. String jsonStrFromServer = "{\n" +
  60. " \"age\": \"\",\n" +
  61. " \"name\": \"zhangsan\"\n" +
  62. "}";
  63. log("------->jsonFromServer:" + jsonStrFromServer);
  64. try {
  65. User2 user2 = gson.fromJson(jsonStrFromServer, User2.class);
  66. log("------>gson 解析:" + user2);
  67. } catch (Exception e) {
  68. log("------>gson 解析異常:" + e);
  69. }
  70. try {
  71. User user = gson.fromJson(jsonStrFromServer, User.class);
  72. log("------>JsonAdapter 注解 解析:" + user);
  73. } catch (JsonParseException e) {//java.lang.NumberFormatException: empty String
  74. log("------>JsonAdapter 注解 異常:" + e);
  75. }
  76. }
  77. }

運(yùn)行結(jié)果:

  1. ------->jsonFromServer:{
  2. "age": "",
  3. "name": "zhangsan"
  4. }
  5. ------>gson 解析異常:com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String
  6. ------>JsonAdapter 注解 解析:User{name='zhangsan', age=0}
可以看到我們成功地跳過服務(wù)端返回json不合理的坑了吧
</pre><pre code_snippet_id="1687762" snippet_file_name="blog_20160519_47_1535429" name="code" class="java">不得不吐槽啊,像這種服務(wù)器端錯(cuò)誤,應(yīng)該完全歸結(jié)服務(wù)端json不合理返回,
往往老板都會(huì)找客戶端原因,怎么又崩潰了?怎么又不顯示了?老板不會(huì)關(guān)心是不是數(shù)據(jù)返回不合理的問題的!
做客戶端需要相當(dāng)?shù)某惺苣芰?同意的點(diǎn)個(gè)贊哈
  1. </pre><p>其實(shí)上面的方式保險(xiǎn)是很保險(xiǎn),但是需要維護(hù)的地方多,代碼量大,我們介紹另外一種方式:JsonSerializer與JsonDeserializer 之關(guān)系單方面的處理,可以全局注冊某個(gè)類型的處理:看實(shí)例:</p><p><pre name="code" class="java">package com.xuan.gson;
  2. import com.google.gson.Gson;
  3. import com.google.gson.GsonBuilder;
  4. import com.google.gson.JsonDeserializationContext;
  5. import com.google.gson.JsonDeserializer;
  6. import com.google.gson.JsonElement;
  7. import com.google.gson.JsonParseException;
  8. import java.lang.reflect.Type;
  9. /**
  10. * @author xuanyouwu
  11. * @email xuanyouwu@163.com
  12. * @time 2016-05-18 11:20
  13. */
  14. public class GsonTest10 {
  15. private static void log(String msg) {
  16. System.out.println(msg);
  17. }
  18. public static class User {
  19. public String name;
  20. public int age;
  21. @Override
  22. public String toString() {
  23. return "User{" +
  24. "name='" + name + '\'' +
  25. ", age=" + age +
  26. '}';
  27. }
  28. }
  29. public static void main(String[] args) throws Exception {
  30. JsonDeserializer<Integer> jsonDeserializer = new JsonDeserializer<Integer>() {
  31. @Override
  32. public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
  33. try {
  34. return json.getAsInt();
  35. } catch (NumberFormatException e) {
  36. return 0;
  37. }
  38. }
  39. };
  40. Gson gson = new GsonBuilder()
  41. .registerTypeAdapter(int.class, jsonDeserializer)
  42. .create();
  43. String jsonStrFromServer = "{\n" +
  44. " \"age\": \"\",\n" +
  45. " \"name\": \"zhangsan\"\n" +
  46. "}";
  47. log("------->jsonFromServer:" + jsonStrFromServer);
  48. try {
  49. User user = gson.fromJson(jsonStrFromServer, User.class);
  50. log("------> JsonDeserializer<Integer> 解析:" + user);
  51. } catch (Exception e) {
  52. log("------> JsonDeserializer<Integer> 解析異常:" + e);
  53. }
  54. Gson gson1=new Gson();
  55. try {
  56. User user1 = gson1.fromJson(jsonStrFromServer, User.class);
  57. log("------> 默認(rèn)gson 解析:" + user1);
  58. } catch (Exception e) {
  59. log("------> 默認(rèn)gson 解析異常:" + e);
  60. }
  61. }
  62. }
運(yùn)行結(jié)果:

------->jsonFromServer:{
    "age": "",
    "name": "zhangsan"
}
------>  JsonDeserializer<Integer> 解析:User{name='zhangsan', age=0}
------>  默認(rèn)gson 解析異常:com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String

 這樣定義全局的反序列化工具就能避免解析異常


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多