How to Pass a Date Parameter in a Restful Way

If you want to know how to pass a date parameter in a restful way, then you should read this article. On this page, you will get a detailed guide on how to accept Date, LocalDate, and LocalDateTime parameters in Spring REST requests, both at the request and application levels.

To begin with, let's consider that we have a Rest Controller with Get request methods that accept LocalDate, LocalTime, and LocalDateTime parameter each.

@RestController
public class DateTimeController {

    @PostMapping("/date")
    public void date(@RequestParam("date") Date date) {
        // ...
    }

    @PostMapping("/localdate")
    public void localDate(@RequestParam("localDate") LocalDate localDate) {
        // ...
    }

    @PostMapping("/localdatetime")
    public void dateTime(@RequestParam("localDateTime") LocalDateTime localDateTime) {
        // ...
    }
}

When sending a POST request to any of those methods with a parameter formatted in accordance with ISO 8601 we'll get an exception. For example, when sending "2021-01-02" to the /date endpoint we will get a bad request error with a message similar to this.

Failed to convert value of type 'java.lang.String' to required type 'java.time.LocalDate'; 
nested exception is org.springframework.core.convert.ConversionFailedException.

This is because Spring by default cannot convert String parameters to any date or time object. That is to say, Spring Boot will convert query parameters value to these Java 8 Date and Time types using the date and time format pattern in the hosting machine's locale settings.

How to Convert Format Pattern on Parameter Level

In order to convert format patterns on parameter levels, one way is to annotate each request parameter with @DateTimeFormat to tell Spring Boot our expected format pattern. Spring will convert the query parameters value using our supplied format pattern.

@RestController
public class DateTimeController {

    @PostMapping("/date")
    public void date(@RequestParam("date") 
      @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date date) {
        // ...
    }

    @PostMapping("/local-date")
    public void localDate(@RequestParam("localDate") 
      @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate localDate) {
        // ...
    }

    @PostMapping("/local-date-time")
    public void dateTime(@RequestParam("localDateTime") 
      @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime localDateTime) {
        // ...
    }
}

How to Convert Format Pattern on Application Level

The useful way to achieve this is to annotate the parameters with the @DateTimeFormat annotation. And you may use a formatting pattern parameter as below.

@Configuration
public class DateTimeConfig extends WebMvcConfigurationSupport {

    @Bean
    @Override
    public FormattingConversionService mvcConversionService() {
        DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false);

        DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar();
        dateTimeRegistrar.setDateFormatter(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
        dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss"));
        dateTimeRegistrar.registerFormatters(conversionService);

        DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar();
        dateRegistrar.setFormatter(new DateFormatter("dd.MM.yyyy"));
        dateRegistrar.registerFormatters(conversionService);

        return conversionService;
    }
}


Leave a reply



Submit