介绍
Gson是谷歌官方推出的支持 JSON -- Java Object相互转换的 Java序列化/反序列化库
Maven依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
使用DEMO
package json.gson;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import json.BaseBean;
import json.DateFormat;
import json.User;
import org.junit.Test;
import java.util.List;
/**
* @describe: gson的使用
* Gson是谷歌官方推出的支持 JSON -- Java Object相互转换的 Java序列化/反序列化库
* @author: houkai
*/
public class GsonDemo {
/**
* 数据类型生成与解析
*/
@Test
public void aTest() {
//基本数据
Gson gson = new Gson();
int i = gson.fromJson("1", int.class);
System.out.println(gson.toJson(i));
//数组
String jsonss = "[\"aa\",\"bb\",\"cc\"]";
String[] ss = gson.fromJson(jsonss, String[].class);
//包装数据
String s = gson.fromJson("str", String.class);
System.out.println(gson.toJson(s));
//自定义对象
User user = User.init();
String userStr = gson.toJson(user);
user = gson.fromJson(userStr, User.class);
System.out.println(user.toString());
}
/**
* 泛型
*/
@Test
public void bTest() {
Gson gson = new Gson();
String jsonss = "[\"1\",\"2\",\"3\"]";
List<String> list = gson.fromJson(jsonss, new TypeToken<List<String>>() {
}.getType());
System.out.println(list);
jsonss = "{\"code\":\"0\",\"data\":[\"1\",\"2\",\"3\"]}";
BaseBean baseBean = gson.fromJson(jsonss, new TypeToken<BaseBean<List<String>>>() {
}.getType());
System.out.println(baseBean.toString());
}
/**
* 时间格式化, 对象中包含事件时的转换,需要指定DateFormat
*/
@Test
public void cTest() {
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
String dateFormatStr = "{\"d\":\"2019-09-09 09:09:09\"}";
DateFormat dateFormat = gson.fromJson(dateFormatStr, DateFormat.class);
System.out.println(dateFormat);
}
/**
* 使用 @SerializedName 注解对对象序列化时进行重命名
*/
@Test
public void dTest(){
String str1 = "{\"name\":\"zha\"}";
String str2 = "{\"nm\":\"zha\"}";
String str3 = "{\"xingming\":\"zha\"}";
Gson gson = new Gson();
SerialReName serialReName = gson.fromJson(str1, SerialReName.class);
gson.fromJson(str2, SerialReName.class);
gson.fromJson(str3, SerialReName.class);
System.out.println(serialReName.toString());
}
/**
* 显示null的值
*/
@Test
public void eTest(){
User user = new User("小明",true,16,null);
Gson gson = new GsonBuilder()
.serializeNulls()
.create();
String userStr = gson.toJson(user);
System.out.println(userStr);
}
/*
* 其它序列化控制
* 1.new GsonBuilder()
* .disableInnerClassSerialization() //内部类不序列化
* .disableHtmlEscaping() //html标签不转义
* .create();
*/
/*
* 注解 @Expose的使用 : 控制对象中的参数是否需要序列化和反序列化,其中:
* @Expose(deserialize = true,serialize = true) //序列化和反序列化都都生效
* @Expose(deserialize = true,serialize = false) //反序列化时生效
* @Expose(deserialize = false,serialize = true) //序列化时生效
* @Expose(deserialize = false,serialize = false) //和不写一样
*
* @Expose(deserialize = false,serialize = false)
* private String homeAddress;// 和不写一样,不管是序列化还是反序列化都和正常使用一样
* 此时,Gson必须通过如下的方式进行实例化:
* Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
*/
/*
* 注解:@Since(int i) 和 @Until(int i)的用法
* @Since(int i)和@Until(int i)是一种版本控制,当版本号大于Since的值时,会解析出该字段,否则不会解析出来,当版本号小于Until的时会解析出来该字段,否则不会。看代码:
* public class User {
* @Since(3) private String name;
* private boolean sex;
* private int age;
* @Until(5) private String homeAddress;
* }
* 解析代码:
* Gson gson = new GsonBuilder().setVersion(int version).create();
* 结果分析:
* 若version<3 则解析结果为:{"homeAddress":“中国xxxxxxxx”,"age":16,"sex":true}
* 若version>=3并且version<5 则解析结果为:{"name":"小明","homeAddress":“中国xxxxxxxx”,"age":16,"sex":true}
* 若version>=5 则解析结果为:{"name":"小明","age":16,"sex":true}
* 其实范围可以概括为,Until之前Since之后;
*
*/
/*
*通过访问修饰符控制序列化和反序列化
* 访问修饰符包括:public、private、protected、static 、final等,注意:static 会自动被排除。
* 通过代码解释:
* public class User {
* private String name;
* public boolean sex;
* static int age;
* final String homeAddress;
* }
*
* Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.FINAL, Modifier.PRIVATE).create();
* System.out.println(gson.toJson(user));
* 结果:{"sex":true}
*/
/*
*TypeAdapter的使用,TypeAdapter 是Gson的一个抽象类,用于接管某种类型的序列化和反序列化过程。
* public abstract class TypeAdapter<T> {
* public abstract void write(JsonWriter out, T value) throws IOException;
* public abstract T read(JsonReader in) throws IOException;
* }
* 使用示例基本类型:
* Gson gson = new GsonBuilder().registerTypeAdapter(Integer.class, new TypeAdapter<Integer>() {
* @Override public void write(JsonWriter out, Integer value) throws IOException {
* out.value(String.valueOf(value));
* }
*
* @Override public Integer read(JsonReader in) throws IOException {
* try {
* return Integer.parseInt(in.nextString());
* } catch (NumberFormatException e) {
* return -1;
* }
* }
* }).create();
*
* 使用示例自定义类型:
* Gson gson = new GsonBuilder().registerTypeAdapter(User.class, new UserTypeAdapter()).create();
* UserTypeAdapter的定义:
* public 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.name("sex").value(value.sex);
* out.name("homeAdress").value(value.homeAdress);
* 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": user.age = in.nextInt(); break;
* case "home":
* case "home_address":
* case "homeAddress": user.homeAddress = in.nextString(); break
* }
* }
* in.endObject();
* return user;
* }
* }
*/
/*
*@JsonAdapter注解的使用
* 该注解必须配合TypeAdpater,JsonSerializer或JsonDeserializer中的一个使用,其中是不需要
* Gson gson = new GsonBuilder().registerTypeAdapter(User.class, new UserTypeAdapter()).create();
* 直接Gson gson = new Gson();既可以将类似UserTypeAdapter的序列化和反序列化规则用于注解的类。
* 使用示例:
* @JsonAdapter(UserTypeAdapter.class)
* public class User {
* private String name;//序列化时生效
* private boolean sex; private int age;
* private String homeAddress;// 和不写一样,不管是序列化还是反序列化都和正常使用一样
* }
*/
/**
* Json 操作
* JsonObject
* JsonArray
* JsonElement
*/
@Test
public void fTest(){
JsonObject object = new JsonObject();
object.addProperty("a", "av");
JsonArray jsonArray = new JsonArray();
jsonArray.add("1");
jsonArray.add("2");
object.add("je", jsonArray);
System.out.println(object);
}
}
public class SerialReName {
@SerializedName(value = "name", alternate = {"nm", "xingming"})
private String name;
@Override
public String toString() {
return "SerialReName{" +
"name='" + name + '\'' +
'}';
}
}
public class BaseBean<T> {
private String code;
private T data;
public BaseBean(String code, T data) {
this.code = code;
this.data = data;
}
@Override
public String toString() {
return "BaseBean{" +
"code='" + code + '\'' +
", data=" + data +
'}';
}
}
public class DateFormat {
private Date d;
@Override
public String toString() {
return "DateFormat{" +
"d=" + d +
'}';
}
}
public class User {
private String name;
private boolean sex;
private int age;
private String homeAddress;
public User(String name, boolean sex, int age, String homeAddress) {
this.name = name;
this.sex = sex;
this.age = age;
this.homeAddress = homeAddress;
}
public static User init(){
return new User("张三", true, 19, "陕西西安");
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", sex=" + sex +
", age=" + age +
", homeAddress='" + homeAddress + '\'' +
'}';
}
}