Gson 模型注解——带有 @SerializedName 的多个反序列化名称

在之前的 Gson 博客文章中,我们介绍了使用 @SerializedName 更改模型属性的(反)序列化命名 。 如果服务器需要(或发送)具有不同名称的属性,我们可以使用 @SerializedName 来解决差异。

在这篇文章中,我们将向大家展示如何将多个名称映射到一个属性。 如果我们的应用程序与多个 API 交互,这将非常有用,这些 API 用不同的名称描述相同的事物。 我们仍然可以使用一个 Java 类作为模型!


扩展模型注解 @SerializedName

在第一篇 @SerializedName 的文章中,我们向大家展示了以下用法:、

public class UserSimple {  
    @SerializedName("fullName")
    String name;

    String email;
    boolean isDeveloper;
    int age;
}

我们将注解添加到模型属性并将序列化和反序列化的名称作为字符串传递。

但这还不是全部! SerializedName 接受两个参数:value 和 alternate。 前者是默认参数。 如果只传递一个字符串,它将设置该值并将 alternate 保留为空值。 但是我们可以专门指定这两个参数:

public class UserSimpleSerializedName {  
    @SerializedName(value = "fullName", alternate = "username")
    private String name;

    private String email;
    private boolean isDeveloper;
    private int age;
}

再一次,值改变了默认序列化和默认反序列化! 因此,如果 Gson 从 Java 模型类创建 JSON,它将使用该值作为名称。

alternate 仅在反序列化期间用作附加选项。 Gson 将检查我们指定的所有名称的 JSON,并尝试找到一个将其映射到带注解的属性。 对于上面的模型类,Gson 会检查传入的 JSON 是否有 fullName 或 username 字段。 任何一个都将映射到 name 属性:

{
    'fullName': 'jiyik',
    'email': 'jiyik_onmpw@163.com'
}
{
    'username': 'jiyik',
    'email': 'jiyik_onmpw@163.com'
}

上面两种 JSON 都会产生相同的 Java 对象。

如果有多个字段匹配一个属性,Gson 将使用最后出现的那个进行映射。 例如,在以下 JSON 中,name 属性将设置为 onmpw,因为该值是后出现的:

{
    'username': 'jiyik',
    'fullName': 'onmpw',
    'email': 'norman@futurestud.io'
}

如果我们的服务器创建不一致的 JSON,则我们永远不知道映射了哪个属性。


总结

在这篇文章中,我们了解了如何进一步利用 @SerializedName 来处理单个属性的多个名称。

请记住,这仅限于反序列化。 Gson 会将各种 JSON 值映射到 Java 对象,但在序列化期间始终创建相同的 JSON。