Gson解析教程

xiaoxiao2021-02-28  22

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

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

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

Gson的实例化方式:

1:Gson gson=newGson();

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

[java] view plain copy gson = new GsonBuilder()                     .setLenient()// json宽松                     .enableComplexMapKeySerialization()//支持Map的key为复杂对象的形式                     .serializeNulls() //智能null                     .setPrettyPrinting()// 调教格式                     .disableHtmlEscaping() //默认是GSON把HTML 转义的                     .create();  

Gson的基本用法:

 JavaBean转换Json字符串

    gson提供 publicString toJson(Object src) 方法可以将对象转换成jsonStr

  

[java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  public class GsonTest1 {      public static class Student {          private String name;          private int age;            //省略setter getter equals      }        private static void log(String msg) {          System.out.println(msg);      }          public static void main(String[] args) throws Exception {          Gson gson = new Gson();          Student student = new Student();          student.setName("xuanyouwu");          student.setAge(26);          String jsonStr = gson.toJson(student);          log("---->javabean convert jsonStr:" + jsonStr);      } }  

运行结果:

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

    List Map转Json字符串

[java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import java.util.Arrays;  import java.util.HashMap;  import java.util.List;  import java.util.Map;  public class GsonTest1 {        private static void log(String msg) {          System.out.println(msg);      }          public static void main(String[] args) throws Exception {          Gson gson = new Gson();            List<String> list = Arrays.asList("1""a""3""rt""5");          log("---->list convert jsonStr:" + gson.toJson(list));            Map<String, Object> content = new HashMap<String, Object>();          content.put("name""xuanyouwu");          content.put("age""26");          log("---->map convert jsonStr:" + gson.toJson(content));      }    }   [java] view plain copy 运行结果:   [java] view plain copy ---->list convert jsonStr:["1","a","3","rt","5"]  ---->map convert jsonStr:{"name":"xuanyouwu","age":"26"}  

       Json字符串转JavaBean

[java] view plain copy String studentJsonStr="{\"name\":\"xuanyouwu\",\"age\":26}";    Student student1 = gson.fromJson(studentJsonStr, Student.class);  log("------->json convert JavaBean:"+student1);         运行结果:

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

   Json字符串转List

[java] view plain copy String listJsonStr="[\"1\",\"a\",\"3\",\"rt\",\"5\"]";   [java] view plain copy Type type = new TypeToken<ArrayList<String>>() { }.getType();  ArrayList<String> sList=gson.fromJson(listJsonStr, type);  log("------->json convert List:"+sList);   [java] view plain copy 运行结果:  json convert List:[1, a, 3, rt, 5

JSONNull

[java] view plain copy JsonNull 其实就是null 字段   [java] view plain copy JsonNull jsonNull=new JsonNull();//构造方法过时,推荐INSTANCE   [java] view plain copy JsonNull jsonNull=JsonNull.INSTANCE;    log("-----"+jsonNull);   [java] view plain copy 运行结果:   [java] view plain copy -----null 

JSONPrimitive    

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

     

[java] view plain copy package com.xuan.gson;  import com.google.gson.JsonNull;  import com.google.gson.JsonPrimitive;  public class GsonTest2 {      private static void log(String msg) {          System.out.println(msg);      }      public static void main(String[] args) throws Exception {          String studentJsonStr="{\"name\":\"xuanyouwu\",\"age\":26}";          log("------>studentJsonStr:"+studentJsonStr);          JsonPrimitive jsonPrimitive=new JsonPrimitive(studentJsonStr);          log("------>jsonPrimitive:"+jsonPrimitive);          log("------>jsonPrimitive:"+jsonPrimitive.toString());          log("------>jsonPrimitive:"+jsonPrimitive.getAsString());            JsonPrimitive jsonPrimitive2=new JsonPrimitive("this is String");          log("------>jsonPrimitive2:"+jsonPrimitive2);          log("------>jsonPrimitive2:"+jsonPrimitive2.toString());          log("------>jsonPrimitive2:"+jsonPrimitive2.getAsString());      }  }  

     运行结果:

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

[java] view plain copy JsonObject jsonObject=new JsonObject();  jsonObject.addProperty("name","xuanyouwu");  jsonObject.addProperty("age",26);  log("------>create jsonObject:"+jsonObject);               运行结果:

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

    创建JsonArray       

[java] view plain copy JsonArray jsonElements=new JsonArray();     jsonElements.add("a");     jsonElements.add("b");     jsonElements.add("c");     jsonElements.add("d");     log("------>create jsonArray:"+jsonElements);             运行结果:

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

     JsonObject 嵌套数组或者说嵌套JsonArray

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

[java] view plain copy JsonObject jsonObject2=new JsonObject();  jsonObject2.addProperty("name","xuanyouwu");  jsonObject2.addProperty("age",26);  JsonArray jsonElements2=new JsonArray();  jsonElements2.add("骑车");  jsonElements2.add("打游戏");  jsonElements2.add("看电视");  jsonObject2.add("hobby",jsonElements2);  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 比较优雅简介

          实例:

[java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import com.google.gson.annotations.SerializedName;  public class GsonTest3 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          public String name;          public int age;          @SerializedName("new")          public int isnew;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      ", age=" + age +                      ", isnew=" + isnew +                      '}';          }      }        public static void main(String[] args) throws Exception {            String jsonFromServer = "{\n" +                  "    \"age\": 26,\n" +                  "    \"name\": \"zhangsan\",\n" +                  "    \"new\": 1\n" +                  "}";          Gson gson = new Gson();          User user = gson.fromJson(jsonFromServer, User.class);          log("------>user:" + user);      }  }  

运行结果: ------>user:User{name='zhangsan', age=26, isnew=1}

[java] view plain copy package com.xuan.gson;    import com.google.gson.Gson;  import com.google.gson.annotations.SerializedName;  public class GsonTest3 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User2 {          public String name;          public int age;          @SerializedName("my_parent_name")          public String pn;            @Override          public String toString() {              return "User2{" +                      "name='" + name + '\'' +                      ", age=" + age +                      ", pn='" + pn + '\'' +                      '}';          }      }        public static void main(String[] args) throws Exception {          String jsonFromServer2="{\n" +                  "    \"age\": 26,\n" +                  "    \"my_parent_name\": \"zhangsanf\",\n" +                  "    \"name\": \"zhangsan\"\n" +                  "}";          Gson gson2 = new Gson();          User2 user2 = gson2.fromJson(jsonFromServer2, User2.class);          log("------>user2:" + user2);      }  }  

运行结果: ------>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的备选字段 会后面的替换前面的

[java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import com.google.gson.annotations.SerializedName; public class GsonTest4 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          public String name;          public int age;          @SerializedName(value = "desc",alternate = {"other","note"})          public String desc;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      ", age=" + age +                      ", desc='" + desc + '\'' +                      '}';          }      }        public static void main(String[] args) throws Exception {          String jsonFromServer = "{\n" +                  "    \"age\": 26,\n" +                  "    \"other\": \"成都人\",\n" +                  "    \"name\": \"zhangsan\"\n" +                  "}";          Gson gson = new Gson();          User user = gson.fromJson(jsonFromServer, User.class);          log("------>user:" + user);              String jsonFromServer2 = "{\n" +                  "    \"age\": 26,\n" +                  "    \"note\": \"成都人\",\n" +                  "    \"name\": \"zhangsan\"\n" +                  "}";          User user2 = gson.fromJson(jsonFromServer2, User.class);          log("------>user:" + user2);            //包括desc 与note note在desc之后          String jsonFromServer3="{\n" +                  "    \"age\": 26,\n" +                  "    \"desc\": \"desc成都人\",\n" +                  "    \"name\": \"zhangsan\",\n" +                  "    \"note\": \"note成都人\"\n" +                  "}";          User user3 = gson.fromJson(jsonFromServer3, User.class);          log("------>user:" + user3);            //包括desc 与note note在desc之前          String jsonFromServer4="{\n" +                  "    \"age\": 26,\n" +                  "    \"note\": \"note成都人\",\n" +                  "    \"name\": \"zhangsan\",\n" +                  "    \"desc\": \"desc成都人\"\n" +                  "}";          User user4 = gson.fromJson(jsonFromServer4, User.class);          log("------>user:" + user4);      }  }     运行结果:

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

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

[java] view plain copy @Retention(RetentionPolicy.RUNTIME)  @Target(ElementType.FIELD)  public @interface Expose {    public boolean serialize() default true;    public boolean deserialize() default true;  }   [java] view plain copy    可以排除不需要序列化的字段,需要配合GsonBuilder使用             Gson gson = new GsonBuilder()     .excludeFieldsWithoutExposeAnnotation()     .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) [java] view plain copy package com.xuan.gson; import com.google.gson.Gson;  import com.google.gson.GsonBuilder;  public class GsonTest5 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          public String name;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      '}';          }      }        public static void main(String[] args) throws Exception {          String jsonFromServer = "{\"name\": \"zhangsan\"}";          Gson gson = new GsonBuilder()                  .excludeFieldsWithoutExposeAnnotation()                  .create();          User user = gson.fromJson(jsonFromServer, User.class);          log("------>反序列化:" + user);            User user1 = new User();          user1.name = "zhangsan2";          String userStr = gson.toJson(user1);          log("------>序列化:" + userStr);      }  }   运行结果: ------>反序列化:User{name='null'} ------>序列化:{} 添加@Expose注解 [java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import com.google.gson.GsonBuilder;  import com.google.gson.annotations.Expose;   public class GsonTest5 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          @Expose //等同于 @Expose(deserialize = true,serialize = true)          public String name;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      '}';          }      }        public static void main(String[] args) throws Exception {          String jsonFromServer = "{\"name\": \"zhangsan\"}";          Gson gson = new GsonBuilder()                  .excludeFieldsWithoutExposeAnnotation()                  .create();          User user = gson.fromJson(jsonFromServer, User.class);          log("------>反序列化:" + user);            User user1 = new User();          user1.name = "zhangsan2";          String userStr = gson.toJson(user1);          log("------>序列化:" + userStr);      }  }  

运行结果:

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

@Expose注解 只序列化

[java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import com.google.gson.GsonBuilder;  import com.google.gson.annotations.Expose;  public class GsonTest5 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          @Expose(deserialize = false,serialize = true)          public String name;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      '}';          }      }        public static void main(String[] args) throws Exception {          String jsonFromServer = "{\"name\": \"zhangsan\"}";          Gson gson = new GsonBuilder()                  .excludeFieldsWithoutExposeAnnotation()                  .create();          User user = gson.fromJson(jsonFromServer, User.class);          log("------>反序列化:" + user);            User user1 = new User();          user1.name = "zhangsan2";          String userStr = gson.toJson(user1);          log("------>序列化:" + userStr);      }  }   运行结果:

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

      @Expose 只反序列化

[java] view plain copy package com.xuan.gson;    import com.google.gson.Gson;  import com.google.gson.GsonBuilder;  import com.google.gson.annotations.Expose;  public class GsonTest5 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          @Expose(deserialize = true, serialize = false)          public String name;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      '}';          }      }        public static void main(String[] args) throws Exception {          String jsonFromServer = "{\"name\": \"zhangsan\"}";          Gson gson = new GsonBuilder()                  .excludeFieldsWithoutExposeAnnotation()                  .create();          User user = gson.fromJson(jsonFromServer, User.class);          log("------>反序列化:" + user);            User user1 = new User();          user1.name = "zhangsan2";          String userStr = gson.toJson(user1);          log("------>序列化:" + userStr);      }  }  

运行结果:

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

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

      结合GsonBuilder.setVersion(n)使用 当n>=v时 才会序列化解析

 

[java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import com.google.gson.GsonBuilder;  import com.google.gson.annotations.Since;  public class GsonTest6 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          @Since(2)          public String name;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      '}';          }      }        public static void main(String[] args) throws Exception {          String jsonFromServer = "{\"name\": \"zhangsan\"}";          Gson gson = new GsonBuilder()                  .setVersion(1)//版本为1                  .create();          User user1 = gson.fromJson(jsonFromServer, User.class);          log("------>反序列化v=1:" + user1);            User user1_1 = new User();          user1_1.name = "zhangsan2";          String userStr = gson.toJson(user1_1);          log("------>序列化v=1:" + userStr);              Gson gson2 = new GsonBuilder()                  .setVersion(2)//版本为2                  .create();          User user2 = gson2.fromJson(jsonFromServer, User.class);          log("------>反序列化v=2:" + user2);            User user2_1 = new User();          user2_1.name = "zhangsan2";          String userStr2_1 = gson2.toJson(user2_1);          log("------>序列化v=2:" + userStr2_1);            Gson gson3 = new GsonBuilder()                  .setVersion(3)//版本为3                  .create();          User user3 = gson3.fromJson(jsonFromServer, User.class);          log("------>反序列化v=3:" + user3);            User user3_1 = new User();          user3_1.name = "zhangsan2";          String userStr3_1 = gson3.toJson(user3_1);          log("------>序列化v=3:" + userStr3_1);      }  }  

运行结果:

------>反序列化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 才解析

[java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import com.google.gson.GsonBuilder;  import com.google.gson.annotations.Until;  public class GsonTest6 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          @Until(2)          public String name;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      '}';          }      }        public static void main(String[] args) throws Exception {          String jsonFromServer = "{\"name\": \"zhangsan\"}";          Gson gson = new GsonBuilder()                  .setVersion(1)//版本为1                  .create();          User user1 = gson.fromJson(jsonFromServer, User.class);          log("------>反序列化v=1:" + user1);            User user1_1 = new User();          user1_1.name = "zhangsan2";          String userStr = gson.toJson(user1_1);          log("------>序列化v=1:" + userStr);            Gson gson2 = new GsonBuilder()                  .setVersion(2)//版本为2                  .create();          User user2 = gson2.fromJson(jsonFromServer, User.class);          log("------>反序列化v=2:" + user2);            User user2_1 = new User();          user2_1.name = "zhangsan2";          String userStr2_1 = gson2.toJson(user2_1);          log("------>序列化v=2:" + userStr2_1);            Gson gson3 = new GsonBuilder()                  .setVersion(3)//版本为3                  .create();          User user3 = gson3.fromJson(jsonFromServer, User.class);          log("------>反序列化v=3:" + user3);            User user3_1 = new User();          user3_1.name = "zhangsan2";          String userStr3_1 = gson3.toJson(user3_1);          log("------>序列化v=3:" + userStr3_1);      }  }   运行结果:

------>反序列化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 Java objects to and from JSON 就是对象json之间的互相转换 接替了T 泛型类的序列化和反序列化的逻辑

   从源码中我们看到区分了2.1版本之前后之后的用法,2.1版本之前可以自定义adapter:

   

[java] view plain copy public class PointAdapter extends TypeAdapter<Point> {   *     public Point read(JsonReader reader) throws IOException {   *       if (reader.peek() == JsonToken.NULL) {   *         reader.nextNull();   *         return null;   *       }   *       String xy = reader.nextString();   *       String[] parts = xy.split(",");   *       int x = Integer.parseInt(parts[0]);   *       int y = Integer.parseInt(parts[1]);   *       return new Point(x, y);   *     }   *     public void write(JsonWriter writer, Point value) throws IOException {   *       if (value == null) {   *         writer.nullValue();   *         return;   *       }   *       String xy = value.getX() + "," + value.getY();   *       writer.value(xy);   *     }   *   }}  

    使用

  

[java] view plain copy GsonBuilder builder = new GsonBuilder();   *   builder.registerTypeAdapter(Point.classnew PointAdapter());   *   // if PointAdapter didn't check for nulls in its read/write methods, you should instead use   *   // builder.registerTypeAdapter(Point.class, new PointAdapter().nullSafe());   *   ...   *   Gson gson = builder.create();  

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

[java] view plain copy //   String json = "{'origin':'0,0','points':['1,2','3,4']}";  //   TypeAdapter<Graph> graphAdapter = gson.getAdapter(Graph.class);  //   Graph graph = graphAdapter.fromJson(json);  // }</pre>  // And an example for serialization: <pre>   {@code  //  //   Graph graph = new Graph(...);  //   TypeAdapter<Graph> graphAdapter = gson.getAdapter(Graph.class);  //   String json = graphAdapter.toJson(graph);  // }</pre>   实例:使用TypeAdapter 来序列化和反序列化 [java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import com.google.gson.TypeAdapter;  public class GsonTest7 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          public String name;          public int age;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      ", age=" + age +                      '}';          }      }        public static void main(String[] args) throws Exception {          Gson gson = new Gson();          TypeAdapter<User> userTypeAdapter = gson.getAdapter(User.class);          User user = new User();          user.name = "xuanyouwu";          user.age = 26;          String userJsonStr = userTypeAdapter.toJson(user);          log("------>序列化:" + userJsonStr);            User user1 = userTypeAdapter.fromJson(userJsonStr);          log("------>反序列化:" + user1);        }  }   [java] view plain copy 运行结果:   [java] view plain copy ------>序列化:{"name":"xuanyouwu","age":26}  ------>反序列化:User{name='xuanyouwu', age=26}   Gson的容错机制: 为什么要容错了,在javaBean中声明了int类型的age 如果服务端 返回的是"" 空字符串怎么办呢?崩溃? 如果json格式不规范如 {name=zhangsan,age:26,hobby=null} 发现不是普通的key value 容错实现方式1: 1:创建Gson的方式 [java] view plain copy gson = new GsonBuilder()                    .setLenient()// json宽松                    .create();   2:使用JsonReader JsonReader jsonReader = gson.newJsonReader(value.charStream()); [java] view plain copy jsonReader.setLenient(true

    3:自定义TypeAdapter

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

 

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

 能解决bug 

[java] view plain copy com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON

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

 实例:

   

[java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import com.google.gson.GsonBuilder;  import com.google.gson.JsonParseException;  import com.google.gson.TypeAdapter;  import com.google.gson.stream.JsonReader;  import com.google.gson.stream.JsonWriter;  import java.io.IOException; public class GsonTest8 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          public String name;          public int age;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      ", age=" + age +                      '}';          }          ;      }        public static class UserTypeAdapter extends TypeAdapter<User> {            @Override          public void write(JsonWriter out, User value) throws IOException {              out.beginObject();              out.name("name").value(value.name);              out.name("age").value(value.age);              out.endObject();          }            @Override          public User read(JsonReader in) throws IOException {              User user = new User();              in.beginObject();              while (in.hasNext()) {                  switch (in.nextName()) {                      case "name":                          user.name = in.nextString();                          break;                      case "age":                          try {                              String str = in.nextString();                              user.age = Integer.valueOf(str);                          } catch (Exception e) {                          }                          break;                  }              }              in.endObject();              return user;          }      }        public static void main(String[] args) throws Exception {          Gson gson = new Gson();            String jsonStrFromServer = "{\n" +                  "    \"age\": \"\",\n" +                  "    \"name\": \"zhangsan\"\n" +                  "}";          log("------->jsonFromServer:"+jsonStrFromServer);          try {              User user = gson.fromJson(jsonStrFromServer, User.class);              log("------>默认Gson 解析:" + user);          } catch (JsonParseException e) {//java.lang.NumberFormatException: empty String              log("------>默认Gson 解析 异常:" + e);          }            Gson gson2 = new GsonBuilder()                  .registerTypeAdapter(User.classnew UserTypeAdapter()).create();          try {              User user2 = gson2.fromJson(jsonStrFromServer, User.class);              log("------>自定义adapter 解析:" + user2);          } catch (JsonParseException e) {//java.lang.NumberFormatException: empty String              log("------>自定义adapter 异常:" + e);          }            try {              UserTypeAdapter userTypeAdapter = new UserTypeAdapter();              User user3 = userTypeAdapter.fromJson(jsonStrFromServer);              log("------>自定义adapter 解析2:" + user3);          } catch (Exception e) {              log("------>自定义adapter 异常2:" + e);          }      }  }  

运行结果:

------->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是空字符串 但是不影响整体的解析流程,这对客户端是十分友好的

  基于注解的方式,上面的方式倾向于整体,注解的方式倾向于字段

  

[java] view plain copy package com.xuan.gson;  import com.google.gson.Gson;  import com.google.gson.JsonParseException;  import com.google.gson.TypeAdapter;  import com.google.gson.annotations.JsonAdapter;  import com.google.gson.stream.JsonReader;  import com.google.gson.stream.JsonWriter;  import java.io.IOException;  public class GsonTest9 {      private static void log(String msg) {          System.out.println(msg);      }        public static class User {          public String name;          @JsonAdapter(IntegerTypeAdapter.class)          public int age;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      ", age=" + age +                      '}';          }      }        public static class IntegerTypeAdapter extends TypeAdapter<Integer> {            @Override          public void write(JsonWriter out, Integer value) throws IOException {              out.value(value);          }            @Override          public Integer read(JsonReader in) throws IOException {              int i = 0;              try {                  String str = in.nextString();                  i = Integer.valueOf(str);              } catch (Exception e) {              }              return i;          }      }        public static class User2 {          public String name;          public int age;            @Override          public String toString() {              return "User{" +                      "name='" + name + '\'' +                      ", age=" + age +                      '}';          }      }      public static void main(String[] args) throws Exception {          Gson gson = new Gson();            String jsonStrFromServer = "{\n" +                  "    \"age\": \"\",\n" +                  "    \"name\": \"zhangsan\"\n" +                  "}";          log("------->jsonFromServer:" + jsonStrFromServer);          try {              User2 user2 = gson.fromJson(jsonStrFromServer, User2.class);              log("------>gson 解析:" + user2);          } catch (Exception e) {              log("------>gson 解析异常:" + e);          }          try {              User user = gson.fromJson(jsonStrFromServer, User.class);              log("------>JsonAdapter 注解 解析:" + user);          } catch (JsonParseException e) {//java.lang.NumberFormatException: empty String              log("------>JsonAdapter 注解 异常:" + e);          }      }  }  

运行结果:

[java] view plain copy ------->jsonFromServer:{      "age""",      "name""zhangsan"  }  ------>gson 解析异常:com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: empty String  ------>JsonAdapter 注解 解析:User{name='zhangsan', age=0}  
转载请注明原文地址: https://www.6miu.com/read-2100040.html

最新回复(0)