Improve default experience of data binding from HTML date and time input fields #24370
Labels
in: web
Issues in web modules (web, webmvc, webflux, websocket)
type: documentation
A documentation task
Milestone
tl;dr
The default Spring MVC date/time form binding is slightly at odds with the way modern date and time form input fields are submitted by browsers. This results in the need for (quite a bit of) explicit binding configuration to make default form submissions from browsers work.
Details
The current Spring MVC way of binding of date value stems from the time when date and time values were handled through simple
<input type="text" … />
elements. When working with those, form values were usually rendered in the format that's matching the user's browser's locale. On form submissions Spring MVC would then consider theLocale
provided (usually in an HTTP header sent by the browser or a value otherwise obtained from the request) when parsing the value provided.The form elements of type
date
andtime
have been specified to contain values that roughly match the ISO formats for dates and times. That means that when using those explicit types, the browser now sends an ISO format but still a browser specific locale. Depending on the actual locale, this might cause the binding to fail, depending on whether the format backing the locale is compatible with the ISO format.Assume a form backing object like this
E.g. a browser submission with German locale with a date of
2019-01-15
and time of20:15
would fail for the date binding, as the German flavor is15.01.2019
but binding the time wouldsucceed as by accident the German format parses ISO times properly.
Solutions / Workarounds
Annotating the form backing object
A very obvious way of fixing this is annotating all relevant form object fields with
@DateTimeFormat(iso = …)
. While this works, it's a bit tedious one you have many of these types. Also, it's a bit surprising that the default configuration is not able to bind the standard values produced by the browser in the first place. On the other hand, Spring MVC cannot actually know whether the value it's supposed to bind is coming from a text field or a date specific one, especially considering the large amounts of existing applications.Define ISO formats to be used for all date types globally
Using Spring MVC's
WebMvcConfigurer
one can tweak the form binding to globally use ISO formats like this:This has the advantage of avoiding the need for additional annotations on form backing objects. It of course breaks the date submission in any other formats (e.g. from plain text input fields using a format other than ISO).
Questions / Remarks
The Spring reference documentation seems a bit dated as it discusses the form binding of dates from the legacy
Date
point of view. Also, declaring a customFormattingConversionService
is not really idiomatic in a Spring Boot context in which you'd rather declare aWebMvcConfigurer
to tweak the service.I was wondering whether it might makes sense to let Boot expose a property to enable the configuration tweaks shown above to simplify switching to the ISO format in general. There's precedence in ISO date specific configuration in the Jackson space.
The text was updated successfully, but these errors were encountered: