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}
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.class, new 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 JSON3,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.class, new 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}