简介
Google Gson是一个简单的基于Java的库,用于将Java对象序列化为JSON,反之亦然。 它是由Google开发的一个开源库。
Gson工具的特性
- 标准化 - Gson是一个由Google管理的标准化库。
- 高效 - 这是对Java标准库的可靠,快速和高效的扩展。
- 优化 - Gson库经过高度优化。
- 支持泛型 - 它为泛型提供了广泛的支持。
- 支持复杂的内部类 - 它支持具有深度继承层次结构的复杂对象。
Gson的特点
这里列出了Gson的一些最显着的特点 -
- 易于使用 - Gson API提供了一个高级外观来简化常用的用例。
- 无需创建映射 - Gson API为大部分要序列化的对象提供了默认映射。
- 性能优 - Gson速度相当快,内存占用量低。 它适用于大型对象图或系统。
- 干净JSON - Gson创建一个干净而紧凑的JSON结果,它易于阅读。
- 无依赖性—Gson库不需要JDK以外的任何其他库。
- 开源 - Gson库是开源的; 它是免费提供的。
处理JSON的三种方法
Gson提供了三种处理JSON的替代方法 -
1. 流媒体API
它读取和写入JSON内容作为离散事件。 JsonReader
和JsonWriter
将数据读取/写入令牌,称为JsonToken
。
这是处理JSON的三种方法中最强大的方法。 它具有最低的开销,并且在读/写操作中速度非常快。 它类似于用于XML的Stax解析器。
2. 树模型
它准备JSON文档的内存树表示。 它构建了一个JsonObject
节点树。 这是一种灵活的方法,类似于XML的DOM解析器。
3. 数据绑定
它使用属性访问器将JSON转换为POJO(普通旧Java对象)并从中转换。 Gson使用数据类型适配器读取/写入JSON。 它类似于XML的JAXB解析器。
以上简介摘自易百教程原文请看
Gson类
Gson是Google Gson库的主要操作类。 它提供了将Java对象转换为匹配的JSON结构的功能,反之亦然。 Gson首先使用GsonBuilder
构建,然后使用toJson(Object)
或fromJson(String,Class)
方法读取/写入JSON构造。
Gson类只有一个无参构造函数
构造函数
- Gson() 只有一个无参构造
类方法(常用)
方法 | 描述 |
---|---|
T fromJson(Reader json, Class classOfT) | 此方法将从指定Reader 读取的Json反序列化为指定类的对象。 |
T fromJson(Reader json, Type typeOfT) | 此方法将从指定reader 读取的Json反序列化为指定类型的对象。 |
T fromJson(String json, Class classOfT) | 此方法将指定的Json反序列化为指定类的对象。 |
T fromJson(String json, Type typeOfT) | 此方法将指定的Json反序列化为指定类型的对象。 |
String toJson(Object src) | 此方法将指定的对象序列化为其等效的Json表示形式。 |
String toJson(Object src, Type typeOfSrc) | 此方法将指定对象(包括泛型类型的对象)序列化为其等效的Json表示形式。 |
String toString() | 转化为字符串的形式。 |
获取Gson类的方式
-
Gson()无参构造函数
Gson gson = new Gson();
-
GsonBuilder构造Gson
// null值也会被序列化 Gson gson = new GsonBuilder().serializeNulls().create(); // 不序列化null值 Gson gson = new GsonBuilder().create();
使用
首先需要先引入相关的工具依赖
maven中:
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<!-- gson依赖 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
<!-- lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
private String name;
private int age;
}
java对象转json(序列化)
Student student = new Student("张三", 21);
// 转成json(序列化)
String s1 = new Gson().toJson(student);
System.out.println(s1);
结果
{"name":"张三","age":21}
json转java对象(反序列化)
String s2 = "{\"name\":\"张三\",\"age\":21}";
// 转成java对象(反序列化)
Student student1 = new Gson().fromJson(s2, Student.class);
System.out.println(student1);
结果
Student(name=张三, age=21)
数组
Gson gson = new Gson();
int[] arrs = {200,300,400};
// 序列化
System.out.println("arrs:" + gson.toJson(arrs));
// 反序列化
arrs = gson.fromJson("[200,300,400]", int[].class);
System.out.println("arrs:" + Arrays.toString(arrs));
结果
arrs:[200,300,400]
arrs:[200, 300, 400]
## 集合
public static void main(String[] args) {
Gson gson = new Gson();
List<Integer> lists = new ArrayList<>();
lists.add(100);
lists.add(90);
lists.add(85);
// 序列化
System.out.print("{");
System.out.print("lists:" + gson.toJson(lists));
System.out.println("}");
// 反序列化
lists = gson.fromJson("[100,90,85]", new TypeToken<List<Integer>>(){}.getType());
System.out.println("lists:" +lists);
}
结果
{lists:[100,90,85]}
lists:[100, 90, 85]
泛型
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("张三", 21));
list.add(new Student("李四", 22));
// 转json
String toJson = new Gson().toJson(list);
System.out.println(toJson);
// 转java泛型集合
String json = "[{\"name\":\"张三\",\"age\":21},{\"name\":\"李四\",\"age\":22}]";
list = new Gson().fromJson(json, new TypeToken<List<Student>>(){}.getType());
System.out.println(list);
}
结果
[{"name":"张三","age":21},{"name":"李四","age":22}]
[Student(name=张三, age=21), Student(name=李四, age=22)]
排除字段
瞬时字段(transient)和静态字段(static)将不会被序列化
排除Modifier为指定类型的字段
// 排除字段是protected修饰的
public static void main(String[] args) {
Student student = new Student("zs", 25);
Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.PROTECTED).create();
String json = gson.toJson(student);
System.out.println(json);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
private String name;
protected int age;
}
结果
{"name":"zs"}
使用@Expose
注解
// 使用@Expose注解的将会被序列化/反序列化
public static void main(String[] args) {
Student student = new Student("zs", 25);
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String json = gson.toJson(student);
System.out.println(json);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
@Expose
private String name;
private int age;
}
结果
{"name":"zs"}
使用ExclusionStrategy定制字段
假如把所有字段以 _
开头的,排除掉
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {
private String name;
private int age;
private String _gender;
}
创建一个定制类
public class ExclusionImpl implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
// 字段以 _ 开头的,排除掉
return fieldAttributes.getName().startsWith("_");
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
return false;
}
}
获取gson
public static void main(String[] args) {
Student student = new Student("zs", 24, "男");
Gson gson = new GsonBuilder()
.setExclusionStrategies(new ExclusionImpl())
.create();
String s = gson.toJson(student);
System.out.println(s);
}
结果
{"name":"zs","age":24}
遇到的问题
java.util.LinkedHashMap cannot be cast to xxx
首先我的实现场景是,通过feign远程调用获取到Result(通用响应)数据,然后获取到data,获取到之后,对data进行遍历,然后报错java.util.LinkedHashMap cannot be cast to xxx
解决
思路:是将我拿到的data数据再次序列化 --> 反序列成集合即可
List<EnterpriseDeviceInfo> enterpriseDeviceInfos = new Gson()
.fromJson(new Gson()
.toJson(enterpriseInfos), new TypeToken<List<EnterpriseDeviceInfo>>(){}.getType());