Generic Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Introduction

In this short tutorial, we'll take a look at how to accept Date, LocalDate and LocalDateTime parameters in Spring REST requests, both at the request and application levels.

2. The Problem

Let's consider a controller with three methods that accept Date, LocalDate and LocalDateTime parameters:

@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 “2018-10-22” 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.

3. Convert Date Parameters on Request Level

One of the ways to handle this problem is to annotate the parameters with the @DateTimeFormat annotation and provide a formatting pattern parameter:

@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) {
        // ...
    }
}

This way, the Strings will be properly converted to date objects, provided the Strings are formatted using the ISO 8601 format.

We can also use our own conversion patterns. We can just provide a pattern parameter in the @DateTimeFormat annotation:

@PostMapping("/date")
public void date(@RequestParam("date") 
  @DateTimeFormat(pattern = "dd.MM.yyyy") Date date) {
    // ...
}

4. Convert Date Parameters at the Application Level

Another way to handle date and time object conversion in Spring is to provide a global configuration. By following the official documentation we should extend the WebMvcConfigurationSupport configuration and extends its mvcConversionService method:

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

First, we create DefaultFormattingConversionService with a false parameter, which means Spring will not register any formatters by default.

Next, we need to register our custom formats for date and date-time parameters. We need to do it by registering two custom formatting registrars. The first one – DateTimeFormatterRegistar will be responsible for parsing the LocalDate and LocaDateTime objects. The second one – DateFormattingRegistrar will handle the Date object.

5. Configure Date-Time in Properties File

Spring gives us an option to set global date-time formats via the application properties file. There are three individual parameters for the date, date-time, and time format:

spring.mvc.format.date=yyyy-MM-dd
spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss
spring.mvc.format.time=HH:mm:ss

All of these parameters can be replaced with iso value. For example setting date-time parameter as:

spring.mvc.format.date-time=iso

will be equal to ISO-8601 formatting:

spring.mvc.format.date-time=yyyy-MM-dd HH:mm:ss

6. Summary

In this article, we've learned how to accept the date parameters in Spring MVC requests. We've covered how to do it per request and globally.

We've also learned how to create our own date formatting patterns.

As always all source code is available over on GitHub.

Generic bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
2 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Comments are closed on this article!