Работа с параметрами даты в Spring

Работа с параметрами даты в Spring

1. Вступление

В этом коротком руководстве мы рассмотрим, как принимать параметрыDate,LocalDate иLocalDateTime в запросах Spring REST как на уровне запроса, так и на уровне приложения.

2. Эта проблема

Давайте рассмотрим контроллер с тремя методами, которые принимают параметрыDate,LocalDate иLocalDateTime:

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

При отправке запроса POST в любой из этих методов с параметром, отформатированным в соответствии с ISO 8601, мы получим исключение.

Например, при отправке «2018-10-22» в конечную точку/date мы получим ошибку неверного запроса с сообщением, похожим на это:

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

Это связано с тем, что Spring по умолчанию не может преобразовать параметры String в любой объект даты или времени.

3. Конвертировать параметры даты на уровне запроса

Один из способов решения этой проблемы - аннотировать параметры саннотацией@DateTimeFormat и предоставить параметр шаблона форматирования:

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

Таким образом, строки будут правильно преобразованы в объекты даты при условии, что строки отформатированы с использованием формата ISO 8601.

Мы также можем использовать наши собственные шаблоны конверсии. Мы можем просто указать параметр шаблона в аннотации@DateTimeFormat:

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

4. Конвертировать параметры даты на уровне приложения

Еще один способ обработки объектов даты и времени в Spring - предоставить глобальную конфигурацию. Мы можем сделать это, выполнивthe official documentation:

@Configuration
class DateTimeConfig {

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

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

        // other desired formatters

        return conversionService;
    }
}

Сначала мы создаемDefaultFormattingConversionService с параметром false, что означает, что Spring по умолчанию не регистрирует никакие средства форматирования.

Затем мы вручную регистрируем новые шаблоны для форматов даты и даты и времени в объектеDateTimeFormatterRegistrar.

5. Резюме

В этой статье мы узнали, как принимать параметры даты в запросах Spring MVC. Мы рассмотрели, как это сделать по запросу и в глобальном масштабе.

Мы также научились создавать собственные шаблоны форматирования даты.

Как всегда доступен весь исходный кодover on GitHub.