Gson 5 个常见错误和问题

在过去的多篇文章中,我们几乎向大家介绍了有关 Gson 的每一个小细节。 是时候退后一步,看看大局了。 在这篇文章中,我们将介绍在生产应用程序中使用 Gson 时会遇到的一些常见错误和问题。

1. Expecting an Object Instead of an Array

大多数 Gson 开发人员在反序列化数据时会在生命周期中的某个时刻看到如下的错误

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $。

它只是告诉我们 JSON 包含一个包含在 [] 中的数组,并且我们的模型在该位置需要一个对象。 如果它是第 1 行且列号较低,则通常是整个模型,它应该是单个对象而不是 Java 数组。 如果它是更高的行,它可能是模型中的嵌套元素。

我们建议仔细查看 JSON 并将其与我们的 Java 模型进行比较。 我们还可以将 jsonschema2pojo 等工具的结果与我们的模型设置进行比较。 我们最终会发现错误的。

2. Expecting an Array Instead of an Object

翻转我们之前的示例也将是我们可能遇到的问题。 如果我们的模型描述了一个数组,但 JSON 包含一个包裹在 {} 中的对象,Gson 将抛出以下错误

java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $。

解决此问题的方法是相同的。 控制我们的 Java 模型设置和 JSON 以找出差异。 一旦两者具有相同的数据结构,Gson 将再次正常工作。

3. Not Re-Using Your Gson Instance

我们几乎所有的文章都包含这样的代码片段:

UserSimple userObject = new UserSimple("jiyik", "jiyik_onmpw@163.com", 26, true);

Gson gson = new Gson();  
String userJson = gson.toJson(userObject);  

优化性能的一种简单方法是跨类共享 Gson 实例。 我们不需要为每次转换都创建一个新的 Gson 实例。 我们可以将其声明为字段属性,并让编写的所有方法重新使用它。 这为我们的应用程序提供了一点额外的性能。

4. 不缩小序列化数据

作为开发人员,Gson 对我们非常友好。 它经常在没有任何额外配置的情况下对数据进行序列化和反序列化。 即使它开箱即用,也不要让它阻止我们对其进一步优化!

例如,在许多应用程序中,Java 模型比服务器实际预期的要复杂得多。 该应用程序将发送比服务器处理更多的数据。 这会消耗不必要的性能,因为 Gson 必须进行不必要的转换。

如果我们的应用程序通过 Internet 发送数据,它还会创建更大的字符串,从而使请求花费更长的时间并消耗用户的数据计划。

我们建议各位看官仔细检查自己发送的内容,如果可能,尽量减少应用的序列化数据。 我们关于排除策略 的博客文章应该为大家提供所有必要的知识。

5. 使用自定义 Setter

正如我们多次解释的那样,Gson 依赖于反射,不会使用我们的自定义 getter 和 setter。 如果我们的模型类在其 setter 中有业务逻辑,我们会遇到一些问题:

public void setFirstName(String firstName) {  
    this.firstName = firstName;

    updateFullName();
}

但是不用担心,我们已经在自定义反序列化器文章中向各位展示了如何在 setter 中使用逻辑。

在这篇文章中,我们了解了一些在使用 Gson 库时可能会导致问题的关键内容。 确保大家在开发阶段取得进展时了解它们。