Version: Spring Boot 2.3.2
I have the following simple TestController
.
@RestController
@RequestMapping("/test")
public class TestController {
@Getter
protected static class TestObj {
@DurationUnit(ChronoUnit.MINUTES)
private Duration breakTime;
}
@GetMapping("/test")
public void test(@RequestBody TestObj test) {
System.out.println(test.getBreakTime());
}
}
With the following body...
{
"breakTime" : 30
}
... what I see in the console is
PT30S
Obviously, conversion is not happening. It always default to SECONDS.
Comment From: wilkinsona
@DurationUnit
is supported by the ApplicationConversionService
that's used for configuration property binding. A separate conversion service, WebConversionService
, is used for conversions when receiving requests and sending responses so you won't get any @DurationUnit
support for web requests/responses.
It looks like we need to clarify the documentation
Comment From: jamestrandung
@wilkinsona Thank you for the clarification. Does that also mean we don't have any support for Duration
as of now in WebConversionService
and Spring Boot in general. I do see other annotations/classes like DurationFormat
and DurationStyle
. Not sure if it can do the job.
Comment From: wilkinsona
Looking more closely at your code snippet, I've also just realised that the WebConversionService
won't be involved either. When you are receiving JSON, Jackson is used to convert the JSON into a Java object. It has its own deserialisers for turning, for example, a JSON string into a Duration
.
DurationFormat
and DurationStyle
are used the customise the behaviour of the Duration-related converters that are registered with the ApplicationConversionService
. If you want to use these for web conversion as well (for request parameters, form binding, etc), you can use a WebMvcConfigurer
and the configure
method on ApplicationConversionService
to set it up:
@Bean
WebMvcConfigurer conversionConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addFormatters(FormatterRegistry registry) {
ApplicationConversionService.configure(registry);
}
};
}