赞
踩
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。 Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象(反序列化),或者反过来(序列化)。
GSON github地址:https://github.com/google/gson
依赖:
Gradle: dependencies { implementation ‘com.google.code.gson:gson:2.8.8’ }
(最新版可自行查看GitHub)
User类,拥有 name, password, age, isStudent 四个属性,对User类型对象进行序列化与反序列化:使 用new Gson().toJson/fromJson即可完成序列化与反序列化。
代码示例:
@Test
public void testObject() {
//java对象
User u1 = new User("Lance", "123", 18, false);
//Gson提供的Gson对象
Gson gson = new Gson();
//序列化
String json = gson.toJson(u1);
System.out.println("序列化:" + json);
//反序列化
User u2 = gson.fromJson(json, User.class);
System.out.println("反序列化:" + u2.getUserName() + "-" + u2.getPassword());
}
运行代码得到的结果:
往User类中增加字段:Job(工作name,薪资salary),对User类型对象进行序列化与反序列化。
代码示例:
@Test
public void testNestedObject() {
//java对象
User u1 = new User("Lance", "123", 18, false);
Job job = new Job("工人", 10000);
u1.setJob(job);
//Gson提供的Gson对象
Gson gson = new Gson();
//序列化
String json = gson.toJson(u1);
System.out.println("序列化:" + json);
User u2 = gson.fromJson(json, User.class);
System.out.println("反序列化:" + u2.getUserName() + "-" + u2.getPassword() +"-"+u2.getJob());
}
运行结果:
数组类型对象和普通对象一样,使用toJson/fromJson即可完成序列化与反序列化。
代码示例:
@Test public void testArray() { User[] users1 = new User[3]; //java对象 users1[0] = new User("Lance", "123", 18, false); users1[1] = new User("Alex", "123", 88, true); //Gson提供的Gson对象 Gson gson = new Gson(); //序列化 String json = gson.toJson(users1); System.out.println("序列化:"+json); User[] users2 = gson.fromJson(json, User[].class); System.out.println("反序列化0:"+users2[0]); System.out.println("反序列化1:"+users2[1]); System.out.println("反序列化2:"+users2[2]); }
运行结果:
List集合类型对象需要注意的是,在反序列化时因为Java是伪泛型,泛型擦除会导致无法反序列化为 List,需要使用TypeToken完成反序列化。
代码示例:
@Test public void testListObject() { List<User> list1 = new ArrayList<>(); list1.add(new User("Lance", "123", 18, false)); list1.add(new User("Alex", "123", 88, true)); list1.add(null); //Gson提供的Gson对象 Gson gson = new Gson(); //序列化 String json = gson.toJson(list1); System.out.println("序列化:"+json); //反序列化 Type type = new TypeToken<List<User>>() { }.getType(); List<User> list2 = gson.fromJson(json, type); System.out.println("反序列化0:"+list2.get(0).getUserName()); System.out.println("反序列化1:"+list2.get(1)); System.out.println("反序列化2:"+list2.get(2)); }
运行结果:
Map集合类型对象在反序列化时与List一样,需要使用TypeToken完成反序列化。
代码示例:
@Test public void testMap() { Map<String, User> map1 = new HashMap<>(); //java对象 map1.put("1", new User("Lance", "123", 18, false)); map1.put("2", new User("Alex", "123", 88, true)); map1.put("3", null); map1.put(null, null); //Gson提供的Gson对象 Gson gson = new Gson(); //序列化 String json = gson.toJson(map1); System.out.println(json); Type type = new TypeToken<Map<String, User>>() { }.getType(); Map<String, User> map2 = gson.fromJson(json, type); System.out.println(map2.get(null)); System.out.println(map2.get("1")); }
运行结果:
Set在反序列化时同样需要使用TypeToken完成反序列化
如果HashSet类型,则完全可以使用反序列为List,因为两者序列化后的Json数据一致!
代码示例:
@Test public void testSet() { Set<User> set1 = new HashSet<>(); set1.add(new User("Lance", "123", 18, false)); set1.add(new User("Alex", "123", 88, true)); set1.add(null); //Gson提供的Gson对象 Gson gson = new Gson(); //序列化 String json = gson.toJson(set1); System.out.println(json); //反序列化 Type type = new TypeToken<Set<User>>() { }.getType(); Set<User> set2 = gson.fromJson(json, type); Iterator<User> iterator = set2.iterator(); while (iterator.hasNext()) { User next = iterator.next(); System.out.println("反序列化:" + next); } }
运行结果:
如果一个变量为NULL,那么按照GSON默认的处理为忽略这个字段
如果一个集合中的存储的数据为NULL,那么按照GSON默认的处理为保留NULL
如果希望JSON字符串字段名不以变量名作为Key,比如JSON字符串中的Key存在Java中的关键字时,可以 借助**@SerializedName**注解控制JSON字段中Key
代码示例:
@Expose
//无法以class作为字段名
@SerializedName("class")
private int cls;
返回结果:
{"userName":"Lance","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关键字,也可以直接让变量不参与序列化/反序列化:
private transient int test2;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。