Gson工具的使用、序列化/反序列化集合、对象、遇到的问题

简介

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内容作为离散事件。 JsonReaderJsonWriter将数据读取/写入令牌,称为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());
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值