Spring Boot @Validアノテーションでバリデーションをシンプルに実装する方法


Spring BootでWebアプリケーションやREST APIを開発していると、リクエストデータのバリデーション(検証)は避けて通れない処理です。例えば、ユーザー登録時に名前やメールアドレスが空でないか、形式が正しいかといったチェックが必要になります。

そんなときに役立つのが、@Validアノテーションです。本記事では、@Validの基本的な役割から、実際のバリデーションルールの定義方法まで、実践的に解説していきます。

@Validとは何か?

@Validは、JavaのJakarta Bean Validation(旧 JSR 303/380)仕様に準拠したバリデーション処理をトリガーするアノテーションです。Spring Bootでは、spring-boot-starter-validationを導入することで、コントローラーの引数やJavaオブジェクトに対して簡単にバリデーションが行えるようになります。

ただし、@Valid自体は「このオブジェクトを検証対象にする」というトリガー的な役割しか持ちません。何をどう検証するかは、フィールドに付ける制約アノテーションで定義します

なぜAPI開発でよく使われるのか?

Spring BootのREST APIでは、クライアントからJSONなどでリクエストデータを受け取ることが一般的です。このとき、受け取ったデータをPOJO(Plain Old Java Object)にマッピングし、@Validを付けることで、Springが自動的にバリデーションを実行してくれます。

@PostMapping("/users")
public ResponseEntity<String> createUser(@RequestBody @Valid UserRequest userRequest) {
  return ResponseEntity.ok("User created");
}

これにより、リクエストが不正な場合は、SpringがMethodArgumentNotValidExceptionをスローし、適切なエラーレスポンスを返すような設計が可能です。

バリデーションの内容はアノテーションで定義する

@Validでバリデーション処理が有効になったオブジェクトには、フィールドごとに制約アノテーションを付けることで、検証内容を細かく制御できます。

public class UserRequest {

  @NotBlank(message = "名前は必須です")
  @Size(min = 2, max = 20, message = "名前は2〜20文字で入力してください")
  private String name;

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

このように、フィールドごとに複数の制約を組み合わせることも可能です。

よく使われる制約アノテーション

バリデーションに使用できる制約アノテーションには、以下のようなものがあります。

アノテーション概要
@NotNullnullであってはならない
@NotBlank空文字や空白のみの文字列は禁止
@NotEmpty空のコレクションや配列、文字列#は禁止
@Size(min=, max=)長さや要素数の制約
@Emailメール形式かどうか
@Pattern(regexp=)正規表現に一致するか
@Min, @Max数値の範囲制約
@Positive, @Negative正数・負数かどうか
@Past, @Future日付が過去か未来か

これらのアノテーションにmessage属性を指定することで、独自のエラーメッセージを定義することもできます。

ネストされたオブジェクトの検証

@Validは、ネストされたオブジェクトにも再帰的にバリデーションを適用できます。

public class OrderRequest {

  @Valid
  private Address address;
}

この場合、Addressクラス内に定義されたバリデーションルールも適用されます。

サービス層での手動バリデーション

コントローラー以外のクラス(たとえばService層)でも、Validatorを使えばバリデーションを明示的に実行できます。

@Service
public class UserService {

  private final Validator validator;

  public UserService(Validator validator) {
    this.validator = validator;
  }

  public void register(UserRequest request) {
    Set<ConstraintViolation<UserRequest>> violations = validator.validate(request);
    if (!violations.isEmpty()) {
      throw new IllegalArgumentException("Validation failed: " + violations);
    }
    // 登録処理
  }
}

@Validatedとの違いと使い分け

Spring独自の@Validatedアノテーションも、@Validと似た用途で使えます。主な違いは、グループバリデーションメソッド単位のバリデーションなど、より柔軟な制御が可能な点です。

@Component
@Validated
public class UserValidator {

  public void validate(@Valid UserRequest request) {
    // 自動的にバリデーションされる
  }
}

まとめ

@Validアノテーションを使うことで、Spring Bootにおける入力値のバリデーションを簡潔かつ柔軟に実装できます。実際のバリデーションルールは、対象フィールドに制約アノテーションを付けることで定義されます。これにより、APIの堅牢性を高めると同時に、ユーザーに対して分かりやすいエラーメッセージを提供することができます。

APIに限らず、任意のコンポーネント内でもValidatorを使ってバリデーションを行えるため、業務ロジックに応じた使い分けも可能です。 ぜひ@Validアノテーションを活用して、より堅牢なアプリケーションを作成してみてください!