Gson Builder - 排除策略
在之前的文章中,我们介绍了一些控制哪些模型属性被(反)序列化的技术。 到目前为止,这一直是在属性层面。 我们可以一次更改一个元素的(反)序列化。 在这篇文章中,我们将研究一种设置更通用规则来控制哪些属性被转换的方法。
使用排除策略超越 transient 和@Expose
我们已经了解了 transient
和 @Expose
,它们会更改单个属性的(反)序列化。 在接下来的内容里,我们将看看更通用的方法。 Gson 称它们为 ExclusionStrategies
。 当然,您必须通过 GsonBuilder 设置它们。
在进入具体实现之前,让我们创建一个测试模型。 我们将使用一个新的 UserDate
模型,它有几个属性:
public class UserDate {
private String _name;
private String email;
private boolean isDeveloper;
private int age;
private Date registerDate = new Date();
}
请特别注意属性类型及其命名。 马上就会变得很重要。 假设我们要踢出所有属性,它们是 Date 或 boolean 类型。 我们可以使用 ExclusionStrategies
轻松做到这一点。 我们可以通过 GsonBuilder
实现它:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return false;
}
@Override
public boolean shouldSkipClass(Class<?> incomingClass) {
return incomingClass == Date.class || incomingClass == boolean.class;
}
});
Gson gson = gsonBuilder.create();
UserDate user = new UserDate("Norman", "norman@futurestud.io", 26, true);
String usersJson = gson.toJson(user);
ExclusionStrategy
类有两个可以覆盖的方法。 我们在上面的例子中只使用了第二个选项。 我们检查了类是 Date 类型还是 boolean 类型。 如果该属性属于任一类型,则该函数将返回 true,而 Gson 将忽略它。 我们可以在此方法中进行任何类检查。 生成的 JSON 将仅包含 string 和 int 类型:
{
"age": 26,
"email": "jiyik_onmpw@163.com",
"_name": "jiyik"
}
另一种方法提供了根据声明排除属性的选项。 例如,如果我们想要排除所有包含下划线 _
的属性,除了上述规则,我们可以使用以下代码:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getName().contains("_");
}
@Override
public boolean shouldSkipClass(Class<?> incomingClass) {
return incomingClass == Date.class || incomingClass == boolean.class;
}
});
Gson gson = gsonBuilder.create();
UserDate user = new UserDate("Norman", "norman@futurestud.io", 26, true);
String usersJson = gson.toJson(user);
这将生成一个非常短的 JSON:
{
"age": 26,
"email": "jiyik_onmpw@163.com"
}
我们可以将排除策略用于许多不同的场景。 如果有一些特定(反)序列化排除的通用系统,它会变得更加容易。 请注意,我们可以将多个排除策略作为参数传递。
如果我们目前没有看到排除策略的意义,那没关系! 我们很快就会更深入地介绍更复杂的类型。 一旦我们开始编写自定义适配器,那么肯定会看到它的价值。 幸运的是,通过排除策略,我们可以将 Gson 设置为忽略任何类。
仅用于序列化或反序列化的排除策略
在上一节中,我们将排除策略应用于序列化和反序列化。 如果我们需要仅用于序列化或反序列化的排除策略,则可以使用以下方法:
- addSerializationExclusionStrategy()
- addDeserializationExclusionStrategy()。
这两种方法的工作方式与之前使用 setExclusionStrategies()
的一般方法相同。 我们可以实现并传递相同的 ExclusionStrategy 对象。
基于修饰符排除字段
正如我们之前所解释的,在序列化和反序列化期间,默认情况下,所有带有 transient
修饰符的模型字段都会被忽略。
GsonBuilder 允许我们更改此行为。 使用 excludeFieldsWithModifiers()
我们可以自定义在(反)序列化期间不包含哪些修饰符。 该方法需要来自 ·java.lang.reflect.Modifier· 类的修饰符之一。
例如,我们可能有以下模型:
public class UserModifier {
private String name;
private transient String email;
private static boolean isDeveloper;
private final int age;
}
如果我们想排除所有最终类型和静态类型的字段,但包括 transient 字段,则需要使用 GsonBuilder 配置 Gson,如下所示:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.excludeFieldsWithModifiers(Modifier.STATIC, Modifier.FINAL);
Gson gson = gsonBuilder.create();
UserModifier user = new UserModifier("jiyik", "jiyik_onmpw@163.com", 26, true);
String usersJson = gson.toJson(user);
上面的代码将创建这个 JSON:
{
"email": "jiyik_onmpw@163.com",
"name": "jiyik"
}
请注意 Gson 实例如何包含 email 字段,即使它是暂时的。 调用 excludeFieldsWithModifiers()
方法会覆盖默认设置。 我们只传递了 static 和 final,因此不会忽略 transient 修饰符。 如果我们希望包含所有字段,无论修饰符如何,只需将一个空列表传递给 excludeFieldsWithModifiers()
。
排除没有 @Expose 的字段
最后,我们不是很喜欢的一个选项,但会提到为我们提供所有选项:excludeFieldsWithoutExposeAnnotation()
。 正如方法名称所表示的,这不包括所有没有 @Expose
注解的字段。
我们可以强制应用程序模型在任何地方都有 @Expose
注解,并确保开发人员考虑哪个字段被(反)序列化。
相关文章
Gson 通过@JsonAdapter 自定义(反)序列化
发布时间:2022/07/24 浏览次数:217 分类:编程语言
-
在这篇文章中,我们将展示如何简化(反)序列化的自定义。 所有这些选项都只能通过自定义 Gson 实例和一些样板代码获得。 Gson 2.7 引入了一个简单的注解,我们可以节省大量代码并获
Gson 自定义反序列化基础
发布时间:2022/07/21 浏览次数:81 分类:编程语言
-
在这篇文章中,我们将了解如何实现自定义 Gson 反序列化。 如果服务器以与客户端的应用程序数据模型不匹配的格式向我们发送数据,请继续阅读!
Gson 自定义实例创建器
发布时间:2022/07/14 浏览次数:121 分类:编程语言
-
在这篇文章中,我们将讨论自定义反序列化的另一个组件。 在过去的几篇文章中,我们探讨了如何自定义数据的序列化和反序列化。 在这两种情况下,我们都试图减轻服务器和客户端之
Gson 循环引用的映射
发布时间:2022/07/13 浏览次数:173 分类:编程语言
-
在这篇文章中,我们将讨论一个特别讨厌的话题:循环引用。 我们可能在计算机科学或图表数学课上听说过循环引用。 在更实际的解释中:它处理对象具有指向不同对象的嵌套属性的情
Gson Builder Floats 和 Doubles 的特殊值
发布时间:2022/07/12 浏览次数:193 分类:编程语言
-
在上一篇 Gson 的文章中,我们研究了使 JSON 转换降低标准的选项。 Lenient 允许传入的 JSON 在某种程度上是非标准的,Gson 仍然能够将其解析为 Java 对象。 在这篇文章中,我们将研究一个
Gson 自定义序列化
发布时间:2022/07/11 浏览次数:117 分类:编程语言
-
在这篇文章中,我们将探讨如何自定义 Java 对象的 Gson 序列化。 我们可能想要更改序列化的原因有很多,例如 简化我们的模型以减少发送的数据量或删除个人信息。 现在我们将通过实
Gson 映射 Enum 枚举
发布时间:2022/07/10 浏览次数:156 分类:编程语言
-
在之前的文章中我们介绍了如何映射嵌套对象、数组和列表、Java Map 等。 在这篇文章中,您将学习如何(反)序列化 Java 枚举 Enum。
Gson 如何反序列化多态对象列表
发布时间:2022/07/09 浏览次数:286 分类:编程语言
-
最近,我们遇到了一种情况,我从 REST 端点接收到 JSON 格式的对象列表。 到目前为止,这没有什么不寻常的,也不是问题。 然而,问题是对象是多态的,需要解析子类特定的字段。 以