GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。
特点: a、快速、高效
b、代码量少、简洁
c、面向对象
d、数据传递和解析方便
Gson的pom依赖:
com.google.code.gson gson 2.8.0
方式一:
Gson gson = new gson();
方式二:通过GsonBuilder(),可以配置多种配置。
Gson gson = new GsonBuilder() .setLenient()// json宽松 .enableComplexMapKeySerialization()//支持Map的key为复杂对象的形式 .serializeNulls() //智能null .setPrettyPrinting()// 调教格式 .disableHtmlEscaping() //默认是GSON把HTML 转义的 .create();
注:JavaBean:
@NoArgsConstructor @AllArgsConstructor @Setter @Getter @ToString @Builder public class PersonJson { private String name; private Integer age; private String hobby; } //hobby是在后面的例子中添加的。要么就name,age两个属性,要么就三个。 //上面的注解是lombok的注解,起到简化Bean类的作用。
public class IndexTest { PersonJson person; @Before public void prepare() { person = new PersonJson("栗霖",18); } @Test public void index() { Gson gson = new Gson(); System.out.println(gson.toJson(person)); System.out.println("---------------"); Gson gson1 = new GsonBuilder().create(); System.out.println(gson1.toJson(person)); } }
结果:
public class IndexTest { PersonJson person; Listlist = new ArrayList<>(); Map map = new HashMap<>(); @Before public void prepare() { person = new PersonJson("栗霖",18); list.add(person); map.put(person.getName(),person); } @Test public void index() { Gson gson = new Gson(); System.out.println("---->List convert json" + gson.toJson(list)); System.out.println("------------------------"); System.out.println("---->map convert json" + gson.toJson(map)); } }
结果:
public class SecondTest { @Test public void index() { String jsonStr = "{\"name\":\"栗霖\",\"age\":\"18\"}"; Gson gson = new GsonBuilder().create(); PersonJson p = gson.fromJson(jsonStr,PersonJson.class); System.out.println("---->jsonStr convert javaBean " + p.getName() + " " + p.getAge()); } }
结果:
public class SecondTest { @Test public void index() { String listJsonStr = "[{\"name\":\"栗霖\",\"age\":\"18\"},{\"name\":\"栗霖之雨\",\"age\":\"18\"}]"; Gson gson = new GsonBuilder().create(); Listlist = gson.fromJson(listJsonStr,new TypeToken >(){}.getType()); System.out.println("---->listJsonStr convert List " + list); } }
结果:
json的抽象基类JsonElemetn:
JsonNull其实就是Null字段
public class SecondTest { @Test public void index() { //JsonNull jsonNull = new JsonNull();该方法已经过时 JsonNull jsonNull = JsonNull.INSTANCE; System.out.println("---->jsonNull " + jsonNull); } }
结果:
jsonPrimitive可以帮助我们获取带转义字符的字符串。这个就不写了。感觉没啥用到。
可以通过addProperty(String,Object)向JsonObject添加属性,跟hashmap类似。
public class SecondTest { @Test public void index() { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("name","栗霖"); jsonObject.addProperty("age",18); System.out.println("---->create jsonObject " + jsonObject); } }
结果:
public class SecondTest { @Test public void index() { JsonArray jsonArray = new JsonArray(); jsonArray.add("a"); jsonArray.add("b"); jsonArray.add("c"); jsonArray.add("d"); System.out.println("---->create jsonArray: " + jsonArray); } }
结果:
JsonObject嵌套数组或者说JsonObject嵌套JsonArray
public class SecondTest { @Test public void index() { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("name","栗霖"); jsonObject.addProperty("age",18); JsonArray jsonArray = new JsonArray(); jsonArray.add("是码农"); jsonArray.add("以前喜欢玩游戏"); jsonArray.add("现在只敢小心积累"); jsonArray.add("只怕突然白了头"); jsonObject.add("status",jsonArray); System.out.println("---->create jsonArray: " + jsonObject); } }
结果:
当你调用其他服务时,他们返回的json KEY值与你的Bean属性名称不对应怎么办?
这时候就需要@SerializedName啦。他可以帮助你解决这个问题!
实体类:
@NoArgsConstructor @AllArgsConstructor @Setter @Getter @ToString @Builder public class PersonJson { private String name; private Integer age; //这里只是随便举个例子,千万不要用中文!!! @SerializedName(value = "爱好") private String hobby; }
示例:
public class SecondTest { JsonObject jsonObject; JsonArray jsonArray; @Before public void index() { jsonObject = new JsonObject(); jsonObject.addProperty("name","栗霖"); jsonObject.addProperty("age",18); jsonArray = new JsonArray(); jsonArray.add("是码农"); jsonArray.add("以前喜欢玩游戏"); jsonArray.add("现在只敢小心积累"); jsonArray.add("只怕突然白了头"); jsonObject.addProperty("爱好",jsonArray.toString()); } @Test public void formal() { Gson gson = new GsonBuilder().create(); PersonJson personJson = gson.fromJson(jsonObject.toString(),PersonJson.class); System.out.println("---->String: " + personJson); } }
结果:
@serializedName
除了value属性外,还可以使用alternate属性,这个值可以替换前面的值,将传入的json进行修改。
注:value的值不能出现在alternate中,alternate是备选字段。
@SerializedName(value = "hobby", alternate = {"interest","be fond of"})
注:默认是既可以序列化,也可以反序列化。一定要配合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字符串转化成对象。
结合GsonBuilder().serVersion(n)使用。当n>=v时,才会解析。
注:也是加在JavaBean属性上使用的。
与@Since相反,这次是n 使用TypeAdapter来实现序列化与反序列化。 代码: 结果: 为什么容错: 如果Bean中定义的是int,但是返回的json对应的是一个""空字串怎么办?这就依赖到了Gson的容错机制。 1)创建宽松Gson 遇到问题,停止解析,以防止报错,功能相对较弱。 2)自定义TypeAdapter 该方法更倾向于整体防止出现异常。 结果: 3)使用注解jsonAdapter,其实质也是自定义Adapter 该方法更倾向于某一个属性的保护。 实体类: Adapter: 测试类: 使用TypeAdapter来序列化和反序列化
public class FiveTest {
@Test
public void index() {
Gson gson = new GsonBuilder().create();
TypeAdapter
Gson的容错机制
Gson gson = new GsonBuilder()
.setLenient()//宽松
.create();
public class ThirdTest {
public static class PersonTypeAdapter extends TypeAdapter
public class PersonJson {
private String name;
@JsonAdapter(IntegerTypeAdapter.class)
private Integer age;
private String hobby;
}
public class IntegerTypeAdapter extends TypeAdapter
public class FourTest {
@Test
public void index() {
Gson gson = new Gson();
String json = "{\"name\":\"栗霖\",\"age\":\"\",\"hobby\":\"篮球吧,读书吧,steam吧\"}";
try {
PersonJson p1 = gson.fromJson(json,PersonJson.class);
System.out.println("---->默认解析 " + p1);
}catch (Exception e) {
System.out.println("---->异常解析,这里json字符串缺失了age的值,真的是怕一转眼就白了头啊" +e);
}
try {
PersonJson p2 = gson.fromJson(json,PersonJson.class);
System.out.println("---->默认解析 " + p2);
}catch (Exception e) {
System.out.println("---->异常解析" + e);
}
}
}