yagibrary

あだ名のやぎと図書館のlibraryを組み合わせてyagibraryです。本から学んだことをみなさんに紹介します。

【読書メモ】【プロになるためのSpring入門】第11章 Spring MVC + Thymeleaf その4

その1~その3に関してはこちらの記事を見てください。
yagibrary.hatenablog.com
yagibrary.hatenablog.com
yagibrary.hatenablog.com

第11章 Spring MVC + Thymeleaf

11.16 入力チェックの実施方法

入力画面が一通り完成したので、次は入力チェックの実施方法を見ていきます。

▼ソース11.32 入力チェックを行うハンドラメソッド

@PostMapping("/reservation/validate-input")
public String validateInput(@Validated ReservationInput reservationInput, ❶
                                            BindingResult bindingResult, ❷
                                            Model model) {
    if (bindingResult.hasErrors()) { ❸
        List<StudentType> studentTypeList = reservationService.findAllStudentType();
        model.addAttribute("studentTypeList", studentTypeList);
        return "reservation/reservationForm";
    }
    ...
    return "reservation/reservationConfirmation";
}

❶では、@Validatedを付けることで、ハンドラメソッドが呼ばれる前に入力チェックが実施されます。

入力チェックの結果は、❷で定義したBindingResult型の引数で渡されます。BindingResultは、Spring MVCが提供する型です。なお、BindingResultの引数は、Inputクラスの引数の右隣に指定しなければならないというルールがあります。

11.17 エラー文言の設定

11.18 リクエストパラメータを使用したハンドラメソッドの呼び分け

11.19 例外のハンドリング

たとえば、ソース11.37の❶の行で、reservationServiceのreserveメソッドを呼び出して研修の予約を行なっていますが、reservationServiceのreserveメソッドは、予約数が定員を超えた場合にCapacityOverExceptionという例外をスローする作りになっている想定です。

▼ソース11.37 研修の定員を超えた場合は例外がスローされる想定

...
@PostMapping(value="/reserve", params="reserve")
public String reserve(@Validated ReservationInput reservationInput, Model model) {
    // 予約数が定員を超えた場合にCapacityOverExceptionがスローされる
    Reservation reservation = reservationService(reservationInput); ❶
    model.addAttribute("reservation", reservation);
    return "reservation/reservationCompletion";
}
...

CapacityOverExceptionオブジェクトがスローされた場合、ソース11.37のハンドラメソッドの中で特に例外のキャッチを行なっていないため、呼び出し元(Spring MVCの内部のプログラム)に例外が伝搬されます。その場合、デフォルトのエラー画面が表示されます。

デフォルトのエラー画面は、ユーザに表示するには不適切です。

例外をハンドリングする方法はいくつかありますが、本章では、例外をスローする可能性があるControllerクラスの中で、@ExceptionHandlerを使用する方法を説明します。

▼ソース11.38 @ExceptionHandlerのサンプル

...
@PostMapping(value="/reservation/reserve", params="order")
public String reserve(@Validated ReservationInput reservationInput, Model model) {
    ...
}

@ExceptionHandler(CapacityOverException.class) ❶
public String displayCapacityOverPage() {
    return "reservation/capacityOver";
}
...