Springで日付パラメータを扱う

1.はじめに

この短いチュートリアルでは、リクエストレベルとアプリケーションレベルの両方で、Spring RESTリクエストで Date LocalDate 、および LocalDateTime パラメータを受け取る方法について説明します。

2.問題

Date LocalDate 、および LocalDateTime パラメータを受け入れる3つのメソッドを持つコントローラを考えてみましょう。

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

ISO 8601に従ってフォーマットされたパラメータを使用してこれらのメソッドのいずれかにPOSTリクエストを送信すると、例外が発生します。

例えば、「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.リクエストレベルで日付パラメータを変換する

この問題を処理する方法の1つは、 __ @ 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で日付と時刻のオブジェクト変換を処理するもう1つの方法は、グローバル構成を提供することです。 公式文書 に従うことでそれを行うことができます。

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

まず、falseパラメータを使用して DefaultFormattingConversionService を作成します。これは、Springがデフォルトでフォーマッタを登録しないことを意味します。

そして、 DateTimeFormatterRegistrar オブジェクトに、日付と日付/時刻形式の新しいパターンを手動で登録します。

5.まとめ

この記事では、Spring MVCリクエストで日付パラメータを受け入れる方法を学びました。リクエストごとにグローバルに行う方法について説明しました。

独自の日付フォーマットパターンを作成する方法も学びました。

いつものように、すべてのソースコードは入手可能ですhttps://github.com/eugenp/tutorials/tree/master/spring-mvc-java[GitHubで動く]