Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Highlight that Duration and Period conversion is provided by the ApplicationConversionService and, by default, is not available for web conversion #22718

Closed
jamestrandung opened this issue Aug 4, 2020 · 3 comments
Assignees
Milestone

Comments

@jamestrandung
Copy link

@jamestrandung jamestrandung commented Aug 4, 2020

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.

@wilkinsona
Copy link
Member

@wilkinsona wilkinsona commented Aug 4, 2020

@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

@jamestrandung
Copy link
Author

@jamestrandung jamestrandung commented Aug 5, 2020

@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.

@philwebb philwebb added this to the 2.2.x milestone Aug 5, 2020
@wilkinsona
Copy link
Member

@wilkinsona wilkinsona commented Aug 5, 2020

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);
		}

	};
}
@wilkinsona wilkinsona changed the title DurationUnit annotation not converting properly Highlight that Duration and Period conversion is provided by the ApplicationConversionService and, by default, is not available for web conversion Aug 5, 2020
@philwebb philwebb modified the milestones: 2.2.x, 2.3.x Dec 16, 2020
@philwebb philwebb modified the milestones: 2.3.x, 2.3.9 Jan 31, 2021
@philwebb philwebb closed this in 549d4f7 Jan 31, 2021
@philwebb philwebb self-assigned this Jan 31, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants