Warm tip: This article is reproduced from serverfault.com, please click

Override JsonDeserializer Behavior

发布于 2021-03-12 15:33:26

The generator has created a field of type OffsetDateTime:

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

But the server actually returns dates in the format: YYYY-mm-dd i.e. 2021-03-07

When using the generated code I get the following warnings:

WARN - Not deserializable: 2021-03-07

What is the correct way to override the deserialization of these fields? Or have these fields deserialize correctly?

Questioner
Conner
Viewed
0
MatKuhr 2021-03-15 16:49:54

An OffsetDateTime should have both a date and a time. The data your service responds with is lacking the time part. As per the OData V4 ABNF, this is not allowed (assuming your service is a V4 service):

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

One way to solve this is to change the property type. You could either:

  1. Change it to Edm.Date in the specification
  2. Or change it to LocalDate in the generated code.

Of course this only makes sense if the service will always respond with a date.


Edit: If you really need to register a custom type adapter (e.g. because the service violates the JSON format) you could override the 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);
    }
}

However, this also requires changing the generated code, because there is currently no convenience to pass a custom type adapter as parameter. Change @JsonAdapter(com.sap.cloud.sdk.datamodel.odatav4.adapter.GsonVdmAdapterFactory.class) to reference your custom factory.

Still, I'd recommend using one of the above workarounds until the service is fixed.