I'm using Spring Framework for my services API and org.joda.time.DateTime
for datetime parsing. Specifically, I'm using the ISOFormatter.dateOptionalTimeParser()
, which allows users the flexibility to use just the date, or both date and time, which is a requirement.
Believe me, I've seen all these related questions that I can already tell people are going to point me towards, e.g. this and this, etc.
Previously, I was taking the date as String
and then processing it using the joda formatter mentioned above in the service layer, but now I want to add request validation in the controller, which means that if the request is syntactically incorrect, the request shouldn't even go to the service layer.
I've tried using multiple variations of @DateTimeFormat(iso = ISO.DATE_TIME)
, as well as specifying the pattern
String in format thing with no luck, whatsoever.
@RequestMapping(value = URIConstants.TEST_URL, method = RequestMethod.GET)
public @ResponseBody String getData(@RequestParam(required = false) DateTime from,
@RequestParam(required = false) DateTime to) {
return dataService.fetchDataFromDB(from, to);
}
What should I do to ensure that the date I get from user complies with the ISO 8601 dateOptionalTime
format? Can I maybe apply multiple patterns to implement this?
ISO 8601 represents date and time by starting with the year, followed by the month, the day, the hour, the minutes, seconds and milliseconds. For example, 2020-07-10 15:00:00.000, represents the 10th of July 2020 at 3 p.m. (in local time as there is no time zone offset specified—more on that below).
You can also create a converter and that will take care of it. I have used OffsetDateTime in the example below, but that can be easily replaced with LocalDateTime. For a detailed article, refer this url - http://www.baeldung.com/spring-mvc-custom-data-binder
Even I was struggling with this for sometime and it wasn't working. The trick is to use the @Component
annotation and did it for me.
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
@Component
public class OffsetDateTimeConverter implements Converter<String, OffsetDateTime> {
@Override
public OffsetDateTime convert(final String source) {
if (source == null || source.isEmpty()) {
return null;
}
return OffsetDateTime.parse(source, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}
}
I ended up creating a POJO for this, where I parse the time from String
using the ISODateTimeFormat.dateOptionalTimeParser()
:
public class DateOptionalTime {
private DateTime date;
private DateTimeFormatter formatter = ISODateTimeFormat.dateOptionalTimeParser();
public DateOptionalTime() {
}
public DateOptionalTime(String date) {
if (date != null) {
this.setDate(formatter.parseDateTime(date));
}
}
public DateTime getDate() {
return date;
}
public void setDate(DateTime date) {
this.date = date;
}
public LocalDateTime getLocalDateTime() {
return date.toLocalDateTime();
}
}
And in the controller, I used it like this:
@RequestMapping(value = URIConstants.TEST_URL, method = RequestMethod.GET)
public @ResponseBody String getData(@RequestParam(required = false) DateOptionalTime from,
@RequestParam(required = false) DateOptionalTime to) {
return dataService.fetchDataFromDB(from, to);
}
It validates the date format according to the ISO standard, and returns BAD_REQUEST status if the format is incorrect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With