Gson 是google解析Json的一个开源框架,同类的框架fastJson,JackJson等等

本人fastJson用了两年,也是从去年才开始接触Gson,希望下面的总结会对博友有用,至于Gson与FastJson的对比,其实半斤八两的问题,不再赘述

第一步:在AS下面创建Java工程 并添加gson依赖

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

Gson的实例化方式:

1:Gson gson=newGson();

2:通过GsonBuilder 可以配置多种选项

  1. gson = new GsonBuilder()
  2. .setLenient()// json宽松
  3. .enableComplexMapKeySerialization()//支持Map的key为复杂对象的形式
  4. .serializeNulls() //智能null
  5. .setPrettyPrinting()// 调教格式
  6. .disableHtmlEscaping() //默认是GSON把HTML 转义的
  7. .create();

Gson的基本用法:

JavaBean转换Json字符串

gson提供 publicString toJson(Object src) 方法可以将对象转换成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. }

运行结果:

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

List Map转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. }
  1. 运行结果:
  1. ---->list convert jsonStr:["1","a","3","rt","5"]
  2. ---->map convert jsonStr:{"name":"xuanyouwu","age":"26"}

Json字符串转JavaBean

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

运行结果:

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

Json字符串转List

  1. 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);
  1. 运行结果:
  1. ------->json convert List:[1, a, 3, rt, 5]
  1. </pre><pre code_snippet_id="1687762" snippet_file_name="blog_20160518_11_939636" name="code" class="java">  Gson封装的类型体系
  1. Gson里面有一个非常有意思的抽象基类JsonElement,他的继承体系:
  1. <img src="https://img-blog.csdn.net/20160518135136864?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
  1. JsonObject等同于org的JSONObject,JsonArray也类似,
  1. JsonNull 其实就是null 字段
  1. JsonNull jsonNull=new JsonNull();//构造方法过时,推荐INSTANCE
  1. JsonNull jsonNull=JsonNull.INSTANCE;
  2. log("-----"+jsonNull);
  1. 运行结果:
  1. -----null

JsonPrimitive非常有意思,我们知道如果json转换成字符串 可能包含引号的转义,但是通过JsonPrimative我们可以获得为转义的字符串,看实例:

  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. }

运行结果:

------>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

创建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);

运行结果:

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

创建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);

运行结果:

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

JsonObject 嵌套数组或者说嵌套JsonArray

通过JsonObject的add(key,JsonElement)可以为jsonObject 添加一个数组的字段

  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);

运行结果:

------>create jsonObject inner JsonArray:{"name":"xuanyouwu","age":26,"hobby":["骑车","打游戏","看电视"]}

Gson注解

在Gson中有五类注解

重命名注解:SerializedName

作用:转换关键字key,json转换成JavaBean时,json字段的key 默认必须和我们声明类的字段名称一样,当服务器端返回了关键字怎么办,比如key 为new switch这样,我们    在声明类的时候不能写这样的字段,可能你想服务器端改动,他可能要改数据库,但是我告诉你,做服务端的大部分不愿意改动他的json,是很自私的!这时候重命名注解都排上用场了   第二种场景:服务器端返回的json 的key 简直太丑,或者太长,你想简化,my_parent_name,可以简化成mpn 比较优雅简介

实例:

  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. }

运行结果: ------>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. }

运行结果: ------>user2:User2{name='zhangsan', age=26, pn='zhangsanf'}

作用2:结合alternate 提供多种备用字段key来解析,@SerializedName(value ="desc",alternate = {"other","note"})  如果json中有other就会解析成desc 如果有note也会解析成desc,注意1:value中的值不能出现在alternate中,注意2:alternate的备选字段 会后面的替换前面的

实例:

  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. }

运行结果:

------>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过滤注解

源码:默认既可以序列化又可以反序列化

  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. }
  1. </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注解的字段将不会解析:
   分为以下几种情况:
    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) 既可以序列化,也可以反序列化
    实例:将分别演示这四种情况



  不添加@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. }
运行结果:
------>反序列化: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. }

运行结果:

------>反序列化: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. }

运行结果:

------>反序列化: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. }

运行结果:

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

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

结合GsonBuilder.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.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. }

运行结果:

------>反序列化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)注解 版本控制

当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. }

运行结果:

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

Gson 高级用法

相信看过retrofit2.0 源码的同学都知道,其中有一个GsonConverterFactory 里面的用法十分精炼老成,这里来一段源码

据说使用TypeAdapter 效率更高,本人还未对比测试,暂时放后吧,TypeAdapter是什么玩意呢?

在源码中备注了一句 Converts Javaobjects to and from JSON 就是对象json之间的互相转换 接替了T 泛型类的序列化和反序列化的逻辑

从源码中我们看到区分了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>
   实例:使用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. }
  1. 运行结果:
  1. ------>序列化:{"name":"xuanyouwu","age":26}
  2. ------>反序列化:User{name='xuanyouwu', age=26}
Gson的容错机制:
   为什么要容错了,在javaBean中声明了int类型的age 如果服务端 返回的是"" 空字符串怎么办呢?崩溃?
   如果json格式不规范如 {name=zhangsan,age:26,hobby=null}  发现不是普通的key value
  容错实现方式1:
  1:创建Gson的方式
  1. gson = new GsonBuilder()
  2. .setLenient()// json宽松
  3. .create();
  2:使用JsonReader  
   JsonReader jsonReader = gson.newJsonReader(value.charStream());
  1. jsonReader.<span style="font-family: 宋体; font-size: 9pt;">setLenient(true)</span>

3:自定义TypeAdapter

4:使用注解JsonAdapter,其实也是自定义Adapter

1.2归为一类 由框架实现,基本json大格式规范,键值对不标准,多引号的问题等等,而不报错停止解析,但是功能相对较弱

能解决bug

  1. com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON<span style="font-family:宋体; font-size:9pt; background-color:rgb(228,228,255)"> </span>

3,4归为一类,都属于自定义adapter,但是3与gson绑定,4使用注解和字段绑定

实例:

  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("------>默认Gson 解析:" + user);
  70. } catch (JsonParseException e) {//java.lang.NumberFormatException: empty String
  71. log("------>默认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. }

运行结果:

------->jsonFromServer:{
    "age": "",
    "name": "zhangsan"
}
------>默认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. }

运行结果:

  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}
  1. 可以看到我们成功地跳过服务端返回json不合理的坑了吧
  1. </pre><pre code_snippet_id="1687762" snippet_file_name="blog_20160519_47_1535429" name="code" class="java">不得不吐槽啊,像这种服务器端错误,应该完全归结服务端json不合理返回,
  1. 往往老板都会找客户端原因,怎么又崩溃了?怎么又不显示了?老板不会关心是不是数据返回不合理的问题的!
  1. 做客户端需要相当的承受能力哈,同意的点个赞哈
  1. </pre><p>其实上面的方式保险是很保险,但是需要维护的地方多,代码量大,我们介绍另外一种方式:JsonSerializer与JsonDeserializer 之关系单方面的处理,可以全局注册某个类型的处理:看实例:</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("------> 默认gson 解析:" + user1);
  58. } catch (Exception e) {
  59. log("------>  默认gson 解析异常:" + e);
  60. }
  61. }
  62. }

运行结果:

------->jsonFromServer:{
    "age": "",
    "name": "zhangsan"
}
------>  JsonDeserializer<Integer> 解析:User{name='zhangsan', age=0}
------>  默认gson 解析异常:com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String

这样定义全局的反序列化工具就能避免解析异常

Gson 是google解析Json的一个开源框架,同类的框架fastJson,JackJson的更多相关文章

  1. Google中Gson的使用解析json数据-------学习篇

    之前写过一篇Gson解析json数据的基本应用,这里不多说,直接上例子. 有兴趣的可以先阅读下之前那篇,这里附上链接: http://www.cnblogs.com/Ant-soldier/p/632 ...

  2. Gson实现自定义解析json格式

    客户端跟服务器交互的时候我们使用json实现 但是 在交互的时候除了传送json对象数据意外 我们还需要传输标志位等 比如我们现在的交互方式格式 对象 { "data": { &q ...

  3. Android 利用Gson生成或解析json

    目前手机端和服务端数据交流格式一般是json,而谷歌提供了Gson来解析json.下载Gson:https://code.google.com/p/google-gson/ 下载的放在lib并导入,若 ...

  4. Amdroid示例:利用Gson生成或解析json

    转自:http://www.cnblogs.com/liqw/p/4266209.html 目前手机端和服务端数据交流格式一般是json,而谷歌提供了Gson来解析json.下载Gson:https: ...

  5. 使用Gson封装和解析JSON

    案例:判断用户名是否存在 在jsp页面使用ajax $("#username").change(function(){ var username = $(this).val(); ...

  6. JSON(3)Google解析Json库Gson

    本文参考 : http://www.cnblogs.com/chenlhuaf/archive/2011/05/01/gson_test.html 1.资料 官网: http://groups.goo ...

  7. Google解析Json库Gson

    1.资料 官网: http://groups.google.com/group/google-gson 代码: https://github.com/google/gson jar包下载: http: ...

  8. Google Reader的另一个开源的替代品Go Read

    Google Reader到7月1号退休了,于是出现了一批Google Reader的替代品,比如Google Reader Is Shutting Down; Here Are the Best A ...

  9. 我的Android进阶之旅------>解决Jackson、Gson解析Json数据时,Json数据中的Key为Java关键字时解析为null的问题

    1.问题描述 首先,需要解析的Json数据类似于下面的格式,但是包含了Java关键字abstract: { ret: 0, msg: "normal return.", news: ...

随机推荐

  1. Linux 权限使用 777 真的好吗?

    Linux 权限使用 777 真的好吗? 开发环境当然不是问题,但是会造成一个习惯,到生产时也容易经常配置成 777. 777 权限可以让你的项目出现很大安全问题.1 linux 775和777权限有 ...

  2. coding 绑定腾讯云开放平台注意事项

    coding升级后需要绑定腾讯云开放平台,按照coding文档的提示操作就好 1.创建腾讯云平台后,不要自定义邮箱和用户名 2.直接绑定原来我们使用的coding账号即可 绑定成功后,邮箱和用户名会自 ...

  3. 网站建设之高速WEB的实现

    1.此文目的 漂亮的色彩.绚丽的动画在输入网址后便能呈现在你的眼前.互联网无可否认已经融入了我们的生活. 我们可以山寨出iPhone却很难有属于自己独特的理念关于事物的思想和心脏. 互联网是现实.艺术 ...

  4. 关于FPGA电源精度要求

    FPGA对DC-DC精度的要求不断提升 FPGA厂商不断采用更先进的工艺来降低器件功耗,提高性能,同时FPGA对供电电源的精度要求也越加苛刻,电压必须维持在非常严格的容限内,如果供电电压范围超出了规范 ...

  5. C++类够做函数初始化列表

    构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式.例如: class CExample{ public: int a; float b; C ...

  6. 10 删除topic中的数据

    1 打开    server.properties2  添加一条:  delete.topic.enable=true 3  执行命令:   bin/kafka-topics.sh --delete ...

  7. Java类的初始化与实例对象的初始化

    Java对象初始化详解 2013/04/10 · 开发 · 1 评论· java 分享到:43 与<YII框架>不得不说的故事—扩展篇 sass进阶篇 Spring事务管理 Android ...

  8. java基础循环

    一. while循环 示例1:.循环打印1到10之间的值 public class Test1 { public static void main(String[] args) { int i=1;/ ...

  9. socket链接循环

    server------------------------#!/usr/bin/env python # encoding: utf-8  # Date: 2018/6/5 import socke ...

  10. HDU-3661-Assignments

    /* Assignments Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...