本文へスキップ
BecomeCoder

Spring / Spring Bootコース · 第6章 実践 ― 実務で通用するSpringアプリへ · レッスン21

不正な入力をはじく ― バリデーションと@Valid

ローカル実施

導入

「名前が空文字」「メールアドレスの形式がおかしい」「年齢がマイナス」——こうした不正なデータをそのままデータベースに保存してしまうと、後々のバグの温床になります。1つずつ if 文でチェックするのは大変です。

説明

Spring Bootでは、DTOのフィールドにバリデーション用のアノテーションを付けるだけで、入力チェックを宣言的に書けます(spring-boot-starter-validation を使用)。

class CreateUserRequest {

    @NotBlank(message = "名前は必須です")
    private String name;

    @Email(message = "メールアドレスの形式が正しくありません")
    private String email;

    @Min(value = 0, message = "年齢は0以上で入力してください")
    private int age;
}

このDTOをControllerで受け取るとき、引数に @Valid を付けます。

@PostMapping
public UserResponse create(@Valid @RequestBody CreateUserRequest request) {
    // ここに到達した時点で、すべてのバリデーションを通過している
    return userService.create(request);
}
graph TD
  Req["リクエストのJSON"] -->|@RequestBodyで変換| DTO["CreateUserRequest"]
  DTO -->|@Validでチェック| Check{"バリデーションOK?"}
  Check -->|OK| Method["メソッドの中身を実行"]
  Check -->|NG| Ex["MethodArgumentNotValidException<br/>が自動的に投げられる"]

@Valid を付けたパラメータがルールに違反していると、メソッドの中身は一切実行されずMethodArgumentNotValidException という例外が自動的に発生します。開発者は「チェックする」というコードを自分で書く必要がなく、「どんなルールか」をアノテーションで宣言するだけで済みます。

アノテーションチェック内容
@NotBlank空文字・null・空白のみを許さない
@NotNullnullを許さない
@Emailメールアドレスの形式
@Min / @Max数値の下限・上限
@Size文字列の長さ・コレクションの要素数

この例外をどうクライアントに伝えるかは、次のレッスンの「例外ハンドリング」で扱います。

やってみよう

「商品登録API」のリクエストDTOに、name(必須)、price(0以上)、description(200文字以内)というフィールドがあるとしたら、それぞれどのバリデーションアノテーションを付ければよいか考えてみましょう。