Validated、Valid、Validator の違いを解説
関連タグ:1. Alibaba Cloud が FIPS 検証済み HSM を提供し暗号鍵セキュリティを強化
2. ドメイン名の有効性
Validated、Valid、Validator の違いを理解していますか
1. 結論から
Valid と Validated の類似点
・どちらのメソッドとパラメータも検証可能
・@Valid と @Validated の両アノテーションにより標準 Bean Validation が適用されます。
検証に失敗した場合、BindException がスローされ、400 (BAD_REQUEST) レスポンスが返されます。また、コントローラー内で Errors または BindingResult パラメータを通じて検証エラーをローカルで処理できます。さらに、パラメータの前に @RequestBody アノテーションがある場合、検証エラーは MethodArgumentNotValidException 例外をスローします。
JSR 380
JSR 380 は Bean Validation の Java API 仕様であり、Jakarta EE および Java SE の一部です。これにより、Bean のプロパティが @NotNull、@Min、@Max などのアノテーションを使用して特定の条件を満たすことを保証します。
このリリースには Java 8 以降が必要で、型アノテーションや Optional、LocalDate などの新しい型のサポートといった Java 8 で追加された新機能を活用しています。
仕様の完全な情報については、JSR 380 を引き続きお読みください。
javax.validation.Valid
oJSR-303 仕様の標準アノテーションサポートであり、マーカーアノテーションです。
oアノテーションは ElementType#METHOD、ElementType#FIELD、ElementType#CONSTRUCTOR、
oElementType#PARAMETER、ElementType#TYPE_USE をサポートします。
・org.springframework.validation.annotation.Validated
oSpring が作成したカスタムアノテーションで、グルーピング機能を強化しています。
oアノテーションは ElementType#TYPE、ElementType#METHOD、ElementType#PARAMETER をサポートします。
@Valid と @Validated の違い
Bean Validation 2.0 (JSR 380) はエンティティおよびメソッド検証のためのメタデータモデルと API を定義しており、Hibernate Validator が現在最も優れた実装です。
Validator インターフェイスには、エンティティ全体またはエンティティの単一プロパティのみを検証するために使用できる 3 つのメソッドがあります。
・Validator#validate() はすべての Bean のすべての制約を検証します
・Validator#validateProperty() は単一プロパティを検証します
・Validator#validateValue() は指定クラスの単一プロパティが正常に検証できるかを確認します
requestBody パラメータ検証であれメソッドレベルの検証であれ、最終的には Hibernate Validator が呼び出されて検証が実行され、Spring Validation はそのラッパー層として機能します。
ユーザー入力の検証は、ほとんどのアプリケーションで共通の機能です。Java エコシステムでは、Java 標準 Bean Validation API を使用してこれをサポートしています。また、バージョン 4.0 以降、Spring とも適切に統合されています。
次のセクションで、これらについて詳しく理解していきましょう。
@Valid アノテーションと @Validated アノテーション
Spring では、メソッドレベルの検証に JSR-303 の @Valid アノテーションを使用します。また、メンバプロパティの検証マークにも使用します。ただし、このアノテーションはグループ検証をサポートしていません。
グループは検証時に適用される制約を制限するのに役立ちます。特殊なユースケースとして UI ウィザードがあります。最初のステップではフィールドのサブグループがあるかもしれません。次のステップでは、同じ Bean に属する別のグループがあるかもしれません。そのため、各ステップでこれらの限定的なフィールドにのみ制約を適用する必要がありますが、@Valid ではこれをサポートできません。
この場合、グループレベルでは Spring の @Validated を使用する必要があります。これは JSR-303 の @Valid の派生版です。メソッドレベルで使用されます。メンバプロパティのマークには、引き続き @Valid アノテーションを使用します。
では、具体例でこれらのアノテーションの使い方を見ていきましょう。

Spring Boot で開発したシンプルなユーザー登録を考えてみましょう。まず、名前とパスワードのプロパティのみを持つようにします。
テストが正常に実行されたことを確認したら、機能を拡張します。次の論理的なステップは、複雑なユーザー登録への変換です。最初のステップでは名前とパスワードをそのままにし、2 番目のステップで年齢や電話番号などの追加情報を取得します。そのため、これらの追加フィールドでドメインオブジェクトを更新します。
ただし、今回は前回のテストが失敗することに気付きます。これは年齢と電話番号のフィールドを渡していないためです。この動作をサポートするには、グループ検証と @Validated アノテーションが必要です。
そのために、フィールドをグループ化して 2 つの異なるグループを作成します。まず、2 つのマーカーインターフェイスを作成する必要があります。各グループまたは各ステップ用に 1 つずつです。グループ検証に関する記事で実装方法を確認できます。ここでは、アノテーションの違いに焦点を当てましょう。
最初のステップ用に BasicInfo インターフェイス、2 番目のステップ用に AdvanceInfo インターフェイスを作成します。さらに、UserAccount クラスを以下のようにこれらのマーカーインターフェイスを使用するように更新します。
次に、@Valid がネストされたプロパティの検証をどのようにトリガーするかを見ていきましょう。
@Valid アノテーションはネストされたプロパティの検証に使用されます。これによりネストされたオブジェクトの検証がトリガーされます。たとえば、現在のシナリオで UserAddress オブジェクトを作成してみましょう。
5. @Valid と @Validated を組み合わせたコレクション検証
リクエストボディが JSON 配列をバックエンドに直接渡し、配列の各項目に対してパラメータ検証を実行したい場合、java.util.Collection の List や Set を直接使用してデータを受け取ると、パラメータ検証が有効になりません。カスタムリストコレクションを使用してパラメータを受け取ることができます。
・List 型をラップし、@Valid アノテーションを宣言します
package com.devicemag.core.BO;
import javax.validation.Valid;
import java.util.*;
まとめ
まとめると、基本的な検証にはメソッド呼び出しで JSR の @Valid アノテーションを使用します。一方、グループシーケンスを含むグループ検証には、メソッド呼び出しで Spring の @Validated アノテーションを使用する必要があります。また、@Valid アノテーションはネストされたプロパティの検証をトリガーするためにも必要です。
Validated は依然として AOP です。メソッド検証では AOP による動的インターセプトを使用し、JSR-303 Validator を使用して検証を完了します。Bean のプロパティ検証では Bean のライフサイクルに基づき、初期化前後に検証が完了します。
2. ドメイン名の有効性
Validated、Valid、Validator の違いを理解していますか
1. 結論から
Valid と Validated の類似点
・どちらのメソッドとパラメータも検証可能
・@Valid と @Validated の両アノテーションにより標準 Bean Validation が適用されます。
検証に失敗した場合、BindException がスローされ、400 (BAD_REQUEST) レスポンスが返されます。また、コントローラー内で Errors または BindingResult パラメータを通じて検証エラーをローカルで処理できます。さらに、パラメータの前に @RequestBody アノテーションがある場合、検証エラーは MethodArgumentNotValidException 例外をスローします。
JSR 380
JSR 380 は Bean Validation の Java API 仕様であり、Jakarta EE および Java SE の一部です。これにより、Bean のプロパティが @NotNull、@Min、@Max などのアノテーションを使用して特定の条件を満たすことを保証します。
このリリースには Java 8 以降が必要で、型アノテーションや Optional、LocalDate などの新しい型のサポートといった Java 8 で追加された新機能を活用しています。
仕様の完全な情報については、JSR 380 を引き続きお読みください。
Valid と Validated の違いは何ですか
javax.validation.Valid
oJSR-303 仕様の標準アノテーションサポートであり、マーカーアノテーションです。
oアノテーションは ElementType#METHOD、ElementType#FIELD、ElementType#CONSTRUCTOR、
oElementType#PARAMETER、ElementType#TYPE_USE をサポートします。
・org.springframework.validation.annotation.Validated
oSpring が作成したカスタムアノテーションで、グルーピング機能を強化しています。
oアノテーションは ElementType#TYPE、ElementType#METHOD、ElementType#PARAMETER をサポートします。
@Valid と @Validated の違い
Validated、Valid、Validator
Bean Validation 2.0 (JSR 380) はエンティティおよびメソッド検証のためのメタデータモデルと API を定義しており、Hibernate Validator が現在最も優れた実装です。
Validator インターフェイスには、エンティティ全体またはエンティティの単一プロパティのみを検証するために使用できる 3 つのメソッドがあります。
・Validator#validate() はすべての Bean のすべての制約を検証します
・Validator#validateProperty() は単一プロパティを検証します
・Validator#validateValue() は指定クラスの単一プロパティが正常に検証できるかを確認します
requestBody パラメータ検証であれメソッドレベルの検証であれ、最終的には Hibernate Validator が呼び出されて検証が実行され、Spring Validation はそのラッパー層として機能します。
ユーザー入力の検証は、ほとんどのアプリケーションで共通の機能です。Java エコシステムでは、Java 標準 Bean Validation API を使用してこれをサポートしています。また、バージョン 4.0 以降、Spring とも適切に統合されています。
次のセクションで、これらについて詳しく理解していきましょう。
@Valid アノテーションと @Validated アノテーション
Spring では、メソッドレベルの検証に JSR-303 の @Valid アノテーションを使用します。また、メンバプロパティの検証マークにも使用します。ただし、このアノテーションはグループ検証をサポートしていません。
グループは検証時に適用される制約を制限するのに役立ちます。特殊なユースケースとして UI ウィザードがあります。最初のステップではフィールドのサブグループがあるかもしれません。次のステップでは、同じ Bean に属する別のグループがあるかもしれません。そのため、各ステップでこれらの限定的なフィールドにのみ制約を適用する必要がありますが、@Valid ではこれをサポートできません。
この場合、グループレベルでは Spring の @Validated を使用する必要があります。これは JSR-303 の @Valid の派生版です。メソッドレベルで使用されます。メンバプロパティのマークには、引き続き @Valid アノテーションを使用します。
では、具体例でこれらのアノテーションの使い方を見ていきましょう。

3. 例
Spring Boot で開発したシンプルなユーザー登録を考えてみましょう。まず、名前とパスワードのプロパティのみを持つようにします。
テストが正常に実行されたことを確認したら、機能を拡張します。次の論理的なステップは、複雑なユーザー登録への変換です。最初のステップでは名前とパスワードをそのままにし、2 番目のステップで年齢や電話番号などの追加情報を取得します。そのため、これらの追加フィールドでドメインオブジェクトを更新します。
ただし、今回は前回のテストが失敗することに気付きます。これは年齢と電話番号のフィールドを渡していないためです。この動作をサポートするには、グループ検証と @Validated アノテーションが必要です。
そのために、フィールドをグループ化して 2 つの異なるグループを作成します。まず、2 つのマーカーインターフェイスを作成する必要があります。各グループまたは各ステップ用に 1 つずつです。グループ検証に関する記事で実装方法を確認できます。ここでは、アノテーションの違いに焦点を当てましょう。
最初のステップ用に BasicInfo インターフェイス、2 番目のステップ用に AdvanceInfo インターフェイスを作成します。さらに、UserAccount クラスを以下のようにこれらのマーカーインターフェイスを使用するように更新します。
次に、@Valid がネストされたプロパティの検証をどのようにトリガーするかを見ていきましょう。
@Valid を使用したネストされた検証
@Valid アノテーションはネストされたプロパティの検証に使用されます。これによりネストされたオブジェクトの検証がトリガーされます。たとえば、現在のシナリオで UserAddress オブジェクトを作成してみましょう。
5. @Valid と @Validated を組み合わせたコレクション検証
リクエストボディが JSON 配列をバックエンドに直接渡し、配列の各項目に対してパラメータ検証を実行したい場合、java.util.Collection の List や Set を直接使用してデータを受け取ると、パラメータ検証が有効になりません。カスタムリストコレクションを使用してパラメータを受け取ることができます。
・List 型をラップし、@Valid アノテーションを宣言します
package com.devicemag.core.BO;
import javax.validation.Valid;
import java.util.*;
まとめ
まとめると、基本的な検証にはメソッド呼び出しで JSR の @Valid アノテーションを使用します。一方、グループシーケンスを含むグループ検証には、メソッド呼び出しで Spring の @Validated アノテーションを使用する必要があります。また、@Valid アノテーションはネストされたプロパティの検証をトリガーするためにも必要です。
Validated は依然として AOP です。メソッド検証では AOP による動的インターセプトを使用し、JSR-303 Validator を使用して検証を完了します。Bean のプロパティ検証では Bean のライフサイクルに基づき、初期化前後に検証が完了します。
