FasterXML / jackson-modules-java8

Set of support modules for Java 8 datatypes (Optionals, date/time) and features (parameter names)
Apache License 2.0
399 stars 116 forks source link

DeserializationFeature ALLOW_DATES_AS_TIMESTAMPS #171

Open benneq opened 4 years ago

benneq commented 4 years ago

With SerializationFeature.WRITE_DATES_AS_TIMESTAMPS it's possible to output date and time data as ISO 8601, but there seems to be no way to only accept date and time data in ISO 8601 format.

Though I'd suggest to add some kind of DeserializationFeature.ALLOW_DATES_AS_TIMESTAMPS or MapperFeature.ALLOW_COERCION_OF_DATES which disables the coercion of date and time data.

In other words: {"myInstant": 123456789} should throw an exception, and only {"myInstant": "1973-11-29T21:33:09Z"} should be allowed.

Or is there already an setting that I missed?

cowtowncoder commented 4 years ago

There is no specific setting that could be used here, although there are multiple ones that could possibly apply, without adding new DeserializationFeature. The main reason I am generally hesitant to add DeserializationFeature is that ideally these would be general-purpose ones (although there are already violations of this, for historical reasons).

Wrt existing things, possibilities include:

But assuming we don't want to use either of above (I think second one would be better, but neither is optimal), there would be choice between new DeserializationFeature for one-off, or, bit bigger work to add DateTimeConfig system detailed at the end here:

https://github.com/FasterXML/jackson-future-ideas/wiki/JSTEP-5

idea of which is to create subset of Date/Time-specific settings, possibly including simple on/off features (DateTimeConfig.Feature.xxx), but not limited to just on/off settings.

What we probably should start doing is to collect kinds of things that need configuring. Coercion settings would be one such feature/aspect. There are also obvious challenges in how to apply different configuration settings (and if possible, allow layered configuration from global/per-type/per-property) that may be overlapping or even conflicting. There is also the question of which settings are per-mapper, immutable during use, and which need to be per-call changeable (DeserializationFeature is one of limited number of things that can be changed in this way).

cowtowncoder commented 4 years ago

One more thing about adding DeserializationFeature: since there is not necessarily a great way to indicate "preferred shape" for given date/time value (there is SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, but that is not even available on deserialization side), it is difficult to have/use general "allow/disallow coercion" (since we do not know which type, timestamp/number, or String, is the canonical form). In that sense it would probably need to be something like ACCEPT_TIMESTAMP_AS_DATE_TIME -- that is, disabling of which would simply prevent reading full Date/Time/DateTime from simple JSON int value.

EDIT:

One minor additional note I realized: use of @JsonFormat (and matching per-type config overrides) does have one possible advantage -- there is the shape property which can specify preferred shape as Shape.STRING (or Shape.NUMBER / Shape.NUMBER_INT). That could establish, if we wanted, strictness regarding allowing (or not) of other shapes.

benneq commented 4 years ago

Yeah, I agree, that the date time stuff is a huge topic.

Right now, i guess a workaround could be to provide a custom set of date time deserializers, that simply checks if the value is a number. If true, throw exception. If false, call the original deserializer.

In that sense it would probably need to be something like ACCEPT_TIMESTAMP_AS_DATE_TIME -- that is, disabling of which would simply prevent reading full Date/Time/DateTime from simple JSON int value.

That sounds reasonable, too.

cowtowncoder commented 4 years ago

After writing all of above, I am beginning to think that DeserializationFeature would make sense (naming to be decided). One reason for this is that there is also possibility of adding matching JsonFormat.Feature (enum that may be set via with and without properties of @JsonFormat), which would then allow 3-level overrides (global, per-type, per-property). At least for 2.x; and then give more time to think of if 3.x should try to unify handling in some way.

cowtowncoder commented 10 months ago

Alternatively, could use newly (2.16) added JavaTimeFeature which is to be used for specifically configuring behavior of this module and nothing else.