【问题标题】:Gson ignore unknown enum valueGson 忽略未知的枚举值
【发布时间】:2011-08-05 22:31:03
【问题描述】:

有没有办法将 gson 配置为忽略未知的枚举值?为了 例子

在我的客户端代码中有一个枚举 DeviceType 有 2 个枚举值:PC, 手机

但是当一个服务器被发送另一种类型例如 MAC 作为另一种 设备类型。如何配置我的 gson 反序列化器以设置 DeviceType = null 而不是抛出异常?

谢谢,

肖恩

【问题讨论】:

  • 如果你不知道合法值,也许你不应该使用枚举?或者,相反,如果值是固定的,那么发送错误值的人应该修复他们的代码而不是发送它们?
  • 这些值是每个版本的固定集。这不会经常更改,但可以在新版本中添加一些。这与协议缓冲区处理得非常好,解析器只是忽略该值并设置为未知字段。我希望 gson 开箱即用地提供类似的东西。
  • 你可能应该只使用一个字符串,如果需要的话,稍后再使用辅助方法来获取一个枚举。此外,如果 Gson 确实支持设置方法(不仅仅是字段),您可以在那里进行转换......但它不(还没有?)

标签: java gson


【解决方案1】:

现在我们可以使用可为空的枚举类型,例如:

data class SomeDTO (
    val type : DeviceType?,
    //other values
)

这样的话,解析不会有任何异常。

【讨论】:

    【解决方案2】:

    您可以轻松编写忽略未知值的自定义JsonDeserializer。阅读更多here。 作为起点,请查看源 gson 源代码,类 com.google.gson.DefaultTypeAdapters.EnumTypeAdapter

    【讨论】:

      【解决方案3】:

      正如我从source code 看到的那样,Gson 完全符合您的要求。

      所以你的异常应该来自另一个地方。仔细查看您的堆栈跟踪(或在此处发布),您可能会在自己的代码中找到 NPE。

      【讨论】:

        【解决方案4】:

        我不能 100% 确定这是否可行,但您可以在枚举上声明一个 static T valueOf(String) 方法来覆盖默认实现,该实现为未知值返回 null 而不是 IllegalArgumentException。

        documentation 建议将使用覆盖的静态实现。

        然后它只取决于 Gson 如何处理该方法的结果(假设 Gson 甚至使用该方法进行解析),但这是一个简单的解决方法,值得一试。

        【讨论】:

        • 不,这行不通。因为 (1) 静态方法不可覆盖(文档建议 Enum.valueOf(Class, String) 与 CertainEnum.valueOf(String),以及 (2) 因为 Gson 在内部使用 name() 和 @SerializedName。github.com/google/gson/blob/…
        • 哇,这是一些 A 级的吹毛求疵。虽然在技术上不是“可覆盖”的方法,但在此示例中,该方法将被隐藏并有效覆盖,这是文档明确所说的可能,我什至说我不知道​​ gson 是如何工作的,并且明确建议将其作为一种简单的解决方法在没有保证的情况下,实际上需要 30 秒的时间进行测试。但是,感谢您进来评论一个 4.5 年前甚至没有被选中的答案,并展示您对一项可能在 4.5 年内轻松改变的技术的了解。
        猜你喜欢
        • 2019-09-16
        • 2015-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多