'How to parse Thymeleaf's th:field value to java.time.Duration?
I am having an issue parsing the th:field's value to a variable of class Duration. What I want to happen is to input some numbers and I want to be saved as minutes.
This is from my HTML file:
<input type="text" th:field="*{duration}">
On my object's side, I just initialized the variable like:
@Column(nullable = false)
private Duration duration;
and I get an error webpage:
Validation failed for object='bookingType'. Error count: 1 org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'bookingType' on field 'duration': rejected value [15]; codes [typeMismatch.bookingType.duration,typeMismatch.duration,typeMismatch.java.time.Duration,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [bookingType.duration,duration]; arguments []; default message [duration]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.Duration' for property 'duration'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@javax.persistence.Column java.time.Duration] for value '15'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [15]]
I am using Bootstrap for the front-end, if it does matter at all.
I added the Thymeleaf's java8time extra, tried changing the input type to time and number, and I still get the same error.
Solution 1:[1]
I generally recommend creating DTO's between your models and web interfaces, so you can move more freely.
You can see in the error and comments, the problem is clear, string input 15 is not a Duration and cannot be converted.
If your Duration value is a specific type (minute, hour ..), you can add a custom converter like this:
public class StringToDurationConverter
implements Converter<String, Duration> {
@Override
public Duration convert(String from) {
return Duration.ofMinutes(
Long.valueOf(from));
}
}
We also need to tell Spring about this new converter by adding the StringToDurationConverter to the FormatterRegistry. This can be done by implementing the WebMvcConfigurer and overriding addFormatters() method:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToDurationConverter());
}
}
The default Spring converter we used will apply the conversion on each matching source-destination pair.
If you want to see something conditional: https://stackoverflow.com/a/57539880/2039546
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | İsmail Y. |
