1.简介
Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象(反序列化),或者反过来(序列化)。
在bulid.gradle中添加依赖
implementation 'com.google.code.gson:gson:2.10.1'
2.Java对象序列化与反序列化
使用new Gson().toJson/fromJson即可完成序列化与反序列化。
@Test
public void testObject() {
//java对象
User user = new User("a404","123456",18,false);
//Gson对象
Gson gson = new Gson();
//序列化
String json = gson.toJson(user);
System.out.println("序列化:"+ json);
//反序列化
User user1 = gson.fromJson(json,User.class);
System.out.println("反序列化:"+ user1.toString());
}
3.Java嵌套对象序列化与反序列化
User类中增加字段:Job(name,salary),对User类型对象进行序列化与反序列化。
@Test
public void testNestedObject() {
User user2 = new User("a404","123456",21,false);
Job job = new Job("jerry",5000);
user2.setJob(job);
Gson gson = new Gson();
String json = gson.toJson(user2);
System.out.println(json);
User user3 = gson.fromJson(json,User.class);
System.out.println(user3.getUsername()+user3.getJob());
}
输出显示是否有嵌套对象不影响序列化与反序列化
4.Array数组的序列化与反序列化
数组类型对象和普通对象一样,使用toJson/fromJson即可完成序列化与反序列化。
@Test
public void arrayTest() {
User[] users = new User[3];
users[0] = new User("a1","123",17,true);
users[1] = new User("a2","456",21,false);
Gson gson = new Gson();
String json = gson.toJson(users);
System.out.println("序列化:"+json);
User[] users1 = gson.fromJson(json,User[].class);
System.out.println("反序列化:"+users1);
System.out.printf("反序列化1:"+users1[0]);
System.out.println("反序列化2:"+users1[1]);
System.out.println("反序列化3:"+users1[2]);
}
5.List的序列化与反序列化
List集合类型对象需要注意的是,在反序列化时因为Java是伪泛型,泛型擦除会导致无法反序列化为List<User>,需要使用TypeToken完成反序列化。
@Test
public void listTest() {
List<User> list = new ArrayList<>();
list.add(new User("a1","1",7,true));
list.add(new User("a2","2",8,false));
list.add(null);
Gson gson = new Gson();
String json = gson.toJson(list);
Type type = new TypeToken<List<User>>() {
}.getType();
List<User> list1 = gson.fromJson(json,type);
System.out.println("反序列化:"+list1);
System.out.println("反序列化:"+list1.get(0).getUsername());
System.out.println("反序列化:"+list1.get(1));
System.out.println("反序列化:"+list1.get(2));
}
6.Map的序列化与反序列化
Map集合类型对象在反序列化时与List一样,需要使用TypeToken完成反序列化。
@Test
public void testMap() {
Map<String, User> map = new HashMap<>();
map.put("1",new User("b","11",18,false));
map.put("2",new User("c","22",25,true));
map.put("3",null);
map.put(null,null);
Gson gson = new Gson();
String json =gson.toJson(map);
System.out.println("序列化:"+json);
Type type = new TypeToken<Map<String, User>>() {
}.getType();
Map<String,User> map1 = gson.fromJson(json,type);
System.out.println("反序列化:"+map1.get(null));
System.out.println("反序列化:"+map1.get("1"));
}
7.Set的序列化与反序列化
Set在反序列化时同样需要使用TypeToken完成反序列化。
@Test
public void testSet() {
Set<User> set = new HashSet<>();
set.add(new User("b","11",18,false));
set.add(new User("c","22",25,true));
set.add(null);
Gson gson = new Gson();
String json = gson.toJson(set);
System.out.println("序列化:"+json);
Type type = new TypeToken<Set<User>>(){}.getType();
Set<User> set1 = gson.fromJson(json,type);
Iterator<User> iterator = set1.iterator();
while (iterator.hasNext()){
User next = iterator.next();
System.out.println("反序列化:"+next);
}
//如果HashSet类型,则完全可以使用反序列为List,因为两者序列化后的Json数据一致
// Type type =new TypeToken<List<User>>(){}.getType();
// List<User> list = gson.fromJson(json,type);
// System.out.println("反序列化:"+list.get(0));
// System.out.println("反序列化:"+list.get(1));
// System.out.println("反序列化:"+list.get(2));
}
8.NULL的序列化与反序列化
如果一个变量为NULL,那么按照GSON默认的处理为忽略这个字段
@Test
public void testNull() {
User user = new User("d","55",6,false);
Gson gson = new Gson();
String json = gson.toJson(user);
System.out.println(json);
User user1 = gson.fromJson(json,User.class);
System.out.println(user1);
System.out.println(user1.getJob());
}
序列化{"username":"d","password":"55","age":6,"isStudent":false}
反序列化User{username='d', password='55', age=6, isStudent=false, job=null}
9.控制序列化/反序列化的变量名称
如果希望JSON字符串字段名不以变量名作为Key,比如JSON字符串中的Key存在Java中的关键字时,可以借助@SerializedName注解控制JSON字段中Key的命名。
@Expose
//无法以class作为字段名
@SerializedName("class")
private int cls;
{"userName":"a","password":"123","age":18,"isStudent":false,"class":2}
如果希望指定GSON对某些字段配置是否参与序列化与反序列化,可以使用 @Expose 注解控制,同时使用GsonBuilder创建Gson对象:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
//serialize:是否参与序列化,deserialize是否参与反序列化
@Expose(serialize = false, deserialize = false)
private int test1;
另外transient关键字,也可以直接让变量不参与序列化/反序列化