java-忽略RuntimeTypeAdapterFactory中未注册的子类型

java-忽略RuntimeTypeAdapterFactory中未注册的子类型,第1张

概述我们有一个将GSON用作转换器的RetrofitAPI,它要求将卡片列表显示给用户.卡遵循以下格式:[{"cardType":"user","data":{}},{"cardType":"content","data":{}}]卡之间的数据属性不同,因此要解

我们有一个将GSON用作转换器的Retrofit API,它要求将卡片列表显示给用户.卡遵循以下格式:

[    {        "cardType": "user",        "data": {}    },    {        "cardType": "content",        "data": {}    }]

卡之间的数据属性不同,因此要解决此问题,我们使用GSON的RuntimeTypeAdapterFactory:

final RuntimeTypeAdapterFactory<Card> factory = RuntimeTypeAdapterFactory        .of(Card.class, "cardType")        .registerSubtype(UserCard.class, "user")        ...        .registerSubtype(ContentCard.class, "content");

但是,我们发现,如果将API更新为包含我们不期望的新cardType,则此 *** 作将无提示地反序列化.默默地说,response.isSuccessful()仍返回true,但response.body()为null.我们能够确定新卡类型的唯一方法是通过反复试验来解决问题.

有什么方法可以让GSON忽略我们尚未注册的任何cardType?如果我们尝试添加此新卡,但应用程序不支持该卡,则我想忽略它.

解决方法:

我认为问题是由于以下事实造成的:RuntimeTypeAdapterFactory在尝试为未注册的类型名称创建适配器时将引发异常(请参见RuntimeTypeAdapterFactorys源代码的摘录):

public <R> TypeAdapter<R> create(Gson gson, Typetoken<R> type) {    ...    // typeFIEldname is the type name that is given when registering the sub type    if (JsonObject.has(typeFIEldname)) {        throw new JsonParseException("cannot serialize " + srcType.getname()            + " because it already defines a fIEld named " + typeFIEldname);    }    ...}

这可能导致Retrofit将整个响应截断为null.

然后查看TypeAdapterFactory的声明:

public interface TypeAdapterFactory {    /**    * Returns a type adapter for {@code type}, or null if this factory doesn't    * support {@code type}.    */    <T> TypeAdapter<T> create(Gson gson, Typetoken<T> type);}

如果您能够返回null而不是抛出该异常,那么我猜Retrofit可以返回它识别的所有子类.

通过扩展RuntimeTypeAdapterFactory并覆盖有问题的方法将很容易处理,但是不幸的是,类被声明为final.

因此,您可以创建一个包装类型的适配器,在其中调用原始的RuntimeTypeAdapter,或者像我那样,只需将类RuntimeTypeAdapterFactory的源复制到您自己的某个包中,并根据需要进行编辑.它是开源的.因此,有问题的部分将是:

if (JsonObject.has(typeFIEldname)) {    log.warn("cannot serialize " + srcType.getname()            + " because it already defines a fIEld named " + typeFIEldname);    return null;}

为了澄清,因为您现在返回的是null而不是抛出异常,所以列表将包含此null元素.要真正忽略它,请确保在实现时调用List.filterNotNull().

总结

以上是内存溢出为你收集整理的java-忽略RuntimeTypeAdapterFactory中未注册的子类型全部内容,希望文章能够帮你解决java-忽略RuntimeTypeAdapterFactory中未注册的子类型所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1092178.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存