I have a Controller which accepts a POJO (MySearch
) representing optional request parameters. Requests succeed when the id
and/or name
parameter(s) are included.
However, if I include the dateTime
parameter like so:
GET /find?dateTime=2019-03-15T22:17:42Z&id=1432&name=Bob
I get an error:
Failed to convert from type [java.lang.String] to type [java.time.ZonedDateTime]
for value '2019-03-15T22:17:42Z'; nested exception is java.lang.IllegalArgumentException:
Parse attempt failed for value [2019-03-15T22:17:42Z]
I also tried annotating the dateTime
field with @DateTimeFormat(iso = ISO.DATE_TIME)
, but that didn't help.
Serialization of ZonedDateTime
fields in other tests successfully format the date/time similar to yyyy-MM-ddTHH:mm:ssZ
in the output.
It is only the deserialization of the ZonedDateTime
field in the POJO that I'm having difficulty with.
@RestController
public class MyController {
@GetMapping("/find")
public MyResponse find(MySearch search) {
// Do stuff ...
}
}
public class MySearch {
private Integer id;
private String name;
private ZonedDateTime dateTime;
}
I configured the ObjectMapper
using these two beans:
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
return Jackson2ObjectMapperBuilder.json()
.modulesToInstall(new Jdk8Module(), new JavaTimeModule())
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
@Bean
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.build();
}
What am I missing, or doing wrong?
Thanks!
If you want to deserialize this object you need to register it as a new converter. In order to do so you can create a class similar to this one:
@Configuration
public class ZoneDateTimeWebMvcConfigurator implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToZoneDateTime());
}
static class StringToZoneDateTime implements Converter<String, ZonedDateTime> {
@Override
public ZonedDateTime convert(String value) {
return ZonedDateTime.parse(value);
}
}
}