Gson的学习与使用

Gson介绍:

GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。

特点: a、快速、高效

b、代码量少、简洁

c、面向对象

d、数据传递和解析方便

Gson的pom依赖:

1 <dependency> 2 <groupId>com.google.code.gson</groupId> 3 <artifactId>gson</artifactId> 4 <version>2.8.0</version> 5 </dependency>

Gson的创建方式:

方式一:

Gson gson = new gson();

方式二:通过GsonBuilder(),可以配置多种配置。

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

Gson的基本用法:

注:JavaBean:

1@NoArgsConstructor 2@AllArgsConstructor 3@Setter 4@Getter 5@ToString 6@Builder 7public class PersonJson { 8 private String name; 9 private Integer age; 10 private String hobby; 11} 12//hobby是在后面的例子中添加的。要么就name,age两个属性,要么就三个。 13//上面的注解是lombok的注解,起到简化Bean类的作用。

Gson提供了public String toJson(Objcet obj)方法,可以将对象转化为json字符串。

JavaBean转化为json字符串

1public class IndexTest { 2 PersonJson person; 3 @Before 4 public void prepare() { 5 person = new PersonJson("栗霖",18); 6 } 7 8 @Test 9 public void index() { 10 Gson gson = new Gson(); 11 System.out.println(gson.toJson(person)); 12 System.out.println("---------------"); 13 Gson gson1 = new GsonBuilder().create(); 14 System.out.println(gson1.toJson(person)); 15 } 16}

结果:

List Map 转化为json字符串

1public class IndexTest { 2 PersonJson person; 3 List<PersonJson> list = new ArrayList<>(); 4 Map<String,PersonJson> map = new HashMap<>(); 5 @Before 6 public void prepare() { 7 person = new PersonJson("栗霖",18); 8 list.add(person); 9 map.put(person.getName(),person); 10 } 11 12 @Test 13 public void index() { 14 Gson gson = new Gson(); 15 System.out.println("---->List convert json" + gson.toJson(list)); 16 System.out.println("------------------------"); 17 System.out.println("---->map convert json" + gson.toJson(map)); 18 } 19}

结果:

Gson提供了public T fromJson(String jsonStr,T.class)方法,可以将json字符串转化为Java对象

json字符串转化为JavaBean

1public class SecondTest { 2 @Test 3 public void index() { 4 String jsonStr = "{\"name\":\"栗霖\",\"age\":\"18\"}"; 5 Gson gson = new GsonBuilder().create(); 6 PersonJson p = gson.fromJson(jsonStr,PersonJson.class); 7 System.out.println("---->jsonStr convert javaBean " + p.getName() + " " + p.getAge()); 8 } 9}

结果:

json字符串转化为list集合

1public class SecondTest { 2 @Test 3 public void index() { 4 String listJsonStr = "[{\"name\":\"栗霖\",\"age\":\"18\"},{\"name\":\"栗霖之雨\",\"age\":\"18\"}]"; 5 Gson gson = new GsonBuilder().create(); 6 List<PersonJson> list = gson.fromJson(listJsonStr,new TypeToken<ArrayList<PersonJson>>(){}.getType()); 7 System.out.println("---->listJsonStr convert List " + list); 8 } 9}

结果:

json的抽象基类JsonElemetn:

JsonNull其实就是Null字段

1public class SecondTest { 2 @Test 3 public void index() { 4 //JsonNull jsonNull = new JsonNull();该方法已经过时 5 JsonNull jsonNull = JsonNull.INSTANCE; 6 System.out.println("---->jsonNull " + jsonNull); 7 } 8}

结果:

jsonPrimitive可以帮助我们获取带转义字符的字符串。这个就不写了。感觉没啥用到。

创建JsonObject:

可以通过addProperty(String,Object)向JsonObject添加属性,跟hashmap类似。

1public class SecondTest { 2 @Test 3 public void index() { 4 JsonObject jsonObject = new JsonObject(); 5 jsonObject.addProperty("name","栗霖"); 6 jsonObject.addProperty("age",18); 7 System.out.println("---->create jsonObject " + jsonObject); 8 } 9}

结果:

创建JsonArray

1public class SecondTest { 2 @Test 3 public void index() { 4 JsonArray jsonArray = new JsonArray(); 5 jsonArray.add("a"); 6 jsonArray.add("b"); 7 jsonArray.add("c"); 8 jsonArray.add("d"); 9 System.out.println("---->create jsonArray: " + jsonArray); 10 } 11}

结果:

JsonObject嵌套数组或者说JsonObject嵌套JsonArray

1public class SecondTest { 2 @Test 3 public void index() { 4 JsonObject jsonObject = new JsonObject(); 5 jsonObject.addProperty("name","栗霖"); 6 jsonObject.addProperty("age",18); 7 JsonArray jsonArray = new JsonArray(); 8 jsonArray.add("是码农"); 9 jsonArray.add("以前喜欢玩游戏"); 10 jsonArray.add("现在只敢小心积累"); 11 jsonArray.add("只怕突然白了头"); 12 jsonObject.add("status",jsonArray); 13 System.out.println("---->create jsonArray: " + jsonObject); 14 } 15}

结果:


Gson注解

重命名注解:@SerializedName

当你调用其他服务时,他们返回的json KEY值与你的Bean属性名称不对应怎么办?

这时候就需要@SerializedName啦。他可以帮助你解决这个问题!

实体类:

1@NoArgsConstructor 2@AllArgsConstructor 3@Setter 4@Getter 5@ToString 6@Builder 7public class PersonJson { 8 private String name; 9 private Integer age; 10 //这里只是随便举个例子,千万不要用中文!!! 11 @SerializedName(value = "爱好") 12 private String hobby; 13}

示例:

1public class SecondTest { 2 JsonObject jsonObject; 3 JsonArray jsonArray; 4 5 @Before 6 public void index() { 7 jsonObject = new JsonObject(); 8 jsonObject.addProperty("name","栗霖"); 9 jsonObject.addProperty("age",18); 10 jsonArray = new JsonArray(); 11 jsonArray.add("是码农"); 12 jsonArray.add("以前喜欢玩游戏"); 13 jsonArray.add("现在只敢小心积累"); 14 jsonArray.add("只怕突然白了头"); 15 jsonObject.addProperty("爱好",jsonArray.toString()); 16 } 17 18 @Test 19 public void formal() { 20 Gson gson = new GsonBuilder().create(); 21 PersonJson personJson = gson.fromJson(jsonObject.toString(),PersonJson.class); 22 System.out.println("---->String: " + personJson); 23 } 24}

结果:

@serializedName

除了value属性外,还可以使用alternate属性,这个值可以替换前面的值,将传入的json进行修改。

注:value的值不能出现在alternate中,alternate是备选字段。

@SerializedName(value = "hobby", alternate = {"interest","be fond of"})

过滤注解@Expose

注:默认是既可以序列化,也可以反序列化。一定要配合GsonBuilder一起使用

该注解是加在JavaBean的属性上使用的。

配合这个使用哦Gson gson = new GsonBuilder().excludeFieldWithoutExposeAnnotation().create();

有四种使用方式:

1)不使用@Expose注解等同于@Expose(deserialize = false, serialize = false)不做任何解析

2)@Expose(deserialize = true, serialize = false)只解析使用,可以反序列化,不可以序列化。

3)@Expose(deserialize = false, serialize = true)可以序列化,不可以反序列化。

4)@Expose(deserialize = false, serialize = true)既可以序列化,也可以反序列化。

注:这里的序列化指:将对象转化为json字符串。反序列化指:将json字符串转化成对象。

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

结合GsonBuilder().serVersion(n)使用。当n>=v时,才会解析。

注:也是加在JavaBean属性上使用的。

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

与@Since相反,这次是n<v时才能够解析。

使用TypeAdapter来实现序列化与反序列化。

使用TypeAdapter来序列化和反序列化

代码:

1public class FiveTest { 2 @Test 3 public void index() { 4 Gson gson = new GsonBuilder().create(); 5 TypeAdapter<PersonJson> typeAdapter = gson.getAdapter(PersonJson.class); 6 String json = "{\"name\":\"栗霖\",\"age\":\"18\",\"hobby\":\"我很是很喜欢FromSoftWare的。大爱宫崎英高,赞美太阳\"}"; 7 PersonJson p = new PersonJson("栗霖",18,"混系列忠实粉丝"); 8 9 System.out.println("---->序列化:是将对象转化为字符串 : " + typeAdapter.toJson(p)); 10 try { 11 System.out.println("---->反序列化:是将字符串转化为对象 : "+ typeAdapter.fromJson(json)); 12 }catch (Exception e) { 13 e.printStackTrace(); 14 } 15 } 16}

结果:

Gson的容错机制

为什么容错:

如果Bean中定义的是int,但是返回的json对应的是一个""空字串怎么办?这就依赖到了Gson的容错机制。

1)创建宽松Gson

遇到问题,停止解析,以防止报错,功能相对较弱。

1Gson gson = new GsonBuilder() 2 .setLenient()//宽松 3 .create();

2)自定义TypeAdapter

该方法更倾向于整体防止出现异常。

1public class ThirdTest { 2 3 public static class PersonTypeAdapter extends TypeAdapter<PersonJson> { 4 @Override 5 public void write(JsonWriter jsonWriter, PersonJson personJson) throws IOException { 6 jsonWriter.beginObject(); 7 jsonWriter.name("name").value(personJson.getName()); 8 jsonWriter.name("age").value(personJson.getAge()); 9 jsonWriter.name("hobby").value(personJson.getHobby()); 10 jsonWriter.endObject(); 11 } 12 13 @Override 14 public PersonJson read(JsonReader jsonReader) throws IOException { 15 PersonJson personJson = new PersonJson(); 16 jsonReader.beginObject(); 17 while (jsonReader.hasNext()) { 18 switch (jsonReader.nextName()) { 19 case "name": 20 personJson.setName(jsonReader.nextString()); 21 break; 22 case "age": 23 try { 24 personJson.setAge(Integer.valueOf(jsonReader.nextString())); 25 } catch (Exception e) { 26 } 27 break; 28 case "hobby": 29 personJson.setHobby(jsonReader.nextString()); 30 } 31 } 32 jsonReader.endObject(); 33 return personJson; 34 } 35 } 36 37 @Test 38 public void index() { 39 Gson gson = new Gson(); 40 41 String json = "{\"name\":\"栗霖\",\"age\":\"\",\"hobby\":\"篮球吧,读书吧,steam吧\"}"; 42 43 System.out.println("----> " + json ); 44 45 try { 46 PersonJson p1 = gson.fromJson(json,PersonJson.class); 47 System.out.println("---->默认解析 " + p1); 48 }catch (Exception e) { 49 System.out.println("---->异常解析,这里json字符串缺失了age的值,真的是怕一转眼就白了头啊" +e); 50 } 51 52 Gson gson1 = new GsonBuilder().registerTypeAdapter(PersonJson.class,new PersonTypeAdapter()).create(); 53 54 try { 55 PersonJson p2 = gson1.fromJson(json,PersonJson.class); 56 System.out.println("---->自定义Adapter 默认解析 "+p2); 57 }catch (Exception e) { 58 System.out.println("---->自定义adapter 异常解析" + e); 59 } 60 61 try { 62 PersonTypeAdapter personTypeAdapter = new PersonTypeAdapter(); 63 PersonJson p3 = personTypeAdapter.fromJson(json); 64 System.out.println("---->自定义Adapter 默认解析 " + p3); 65 }catch (Exception e){ 66 System.out.println("---->自定义Adapter 异常解析 " +e); 67 } 68 } 69}

结果:

3)使用注解jsonAdapter,其实质也是自定义Adapter

该方法更倾向于某一个属性的保护。

实体类:

1public class PersonJson { 2 private String name; 3 @JsonAdapter(IntegerTypeAdapter.class) 4 private Integer age; 5 private String hobby; 6}

Adapter:

1public class IntegerTypeAdapter extends TypeAdapter<Integer>{ 2 @Override 3 public void write(JsonWriter jsonWriter, Integer integer) throws IOException { 4 jsonWriter.value(integer); 5 } 6 7 @Override 8 public Integer read(JsonReader jsonReader) throws IOException { 9 int i = 0; 10 try { 11 i = Integer.valueOf(jsonReader.nextString()); 12 }catch (Exception e){} 13 return i; 14 } 15}

测试类:

1public class FourTest { 2 3 @Test 4 public void index() { 5 Gson gson = new Gson(); 6 String json = "{\"name\":\"栗霖\",\"age\":\"\",\"hobby\":\"篮球吧,读书吧,steam吧\"}"; 7 8 try { 9 PersonJson p1 = gson.fromJson(json,PersonJson.class); 10 System.out.println("---->默认解析 " + p1); 11 }catch (Exception e) { 12 System.out.println("---->异常解析,这里json字符串缺失了age的值,真的是怕一转眼就白了头啊" +e); 13 } 14 15 try { 16 PersonJson p2 = gson.fromJson(json,PersonJson.class); 17 System.out.println("---->默认解析 " + p2); 18 }catch (Exception e) { 19 System.out.println("---->异常解析" + e); 20 } 21 } 22}

结果:

本文参考:http://blog.csdn.net/axuanqq/article/details/51441590,学习整理。如果你觉得喜欢不妨点个赞,如果你觉得哪里有问题欢迎留言讨论。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

一篇文章带你了解JavaScript日期

日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang