【问题标题】:Override JsonDeserializer Behavior覆盖 JsonDeserializer 行为
【发布时间】:2021-03-12 15:33:26
【问题描述】:

生成器创建了一个 OffsetDateTime 类型的字段:

@Nullable
@ElementName("DocDate")
private OffsetDateTime docDate;

但服务器实际上以以下格式返回日期:YYYY-mm-dd 即2021-03-07

使用生成的代码时,我收到以下警告:

WARN - Not deserializable: 2021-03-07

覆盖这些字段的反序列化的正确方法是什么?或者这些字段是否正确反序列化?

【问题讨论】:

  • 嗨康纳,欢迎来到 SO。服务是 OData V4 吗?另外,服务中的字段是否定义为 Edm.DateTimeOffset?

标签: sap-cloud-sdk


【解决方案1】:

OffsetDateTime 应该有日期和时间。您的服务响应的数据缺少时间部分。根据OData V4 ABNF,这是不允许的(假设您的服务是 V4 服务):

dateTimeOffsetValue = year "-" month "-" day "T" hour ":" minute [ ":" second [ "." fractionalSeconds ] ] ( "Z" / SIGN hour ":" minute )

解决此问题的一种方法是更改​​属性类型。你可以:

  1. 在规范中改为Edm.Date
  2. 或者在生成的代码中改成LocalDate

当然,这只有在服务总是以日期响应时才有意义。


编辑:如果您确实需要注册自定义类型适配器(例如,因为服务违反 JSON 格式),您可以覆盖 GsonVdmAdapterFactory

public <T> TypeAdapter<T> create( @Nonnull final Gson gson, @Nonnull final TypeToken<T> type )
{
    if( LocalDate.class.isAssignableFrom(rawType) ) {
        return (TypeAdapter<T>) new CustomLocalDateTypeAdapter();
    } else {
        return super.create(gson, type);
    }
}

但是,这也需要更改生成的代码,因为目前不方便将自定义类型适配器作为参数传递。更改 @JsonAdapter(com.sap.cloud.sdk.datamodel.odatav4.adapter.GsonVdmAdapterFactory.class) 以引用您的自定义工厂。

不过,我还是建议在服务修复之前使用上述解决方法之一。

【讨论】:

  • SAP B1 定义将其列为&lt;Property Name="DocDate" Type="Edm.DateTimeOffset"/&gt;,但实际上返回的日期没有任何时间信息。我可以修改生成的代码以反映它。我想知道是否有更优雅的方式来处理这个问题,但上述方法有效。
  • 如果服务总是以Date 响应,那么我认为调整规范直到它被服务修复是最好的方法。如果由于某种原因现有的解析逻辑不是一个解决方案,我扩展了我的答案,如果绝对必要的话,如何注册自定义类型适配器。
  • 有道理,不幸的是我认为这个规范不会很快改变。我会根据需要继续修改客户端代码。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
  • 2016-05-27
  • 2021-08-01
  • 2012-03-18
  • 1970-01-01
  • 2011-04-28
相关资源
最近更新 更多