[Spring] Bean Validation


Ben Validator:インタフェース
Hibernate Validator:実装
例)
@NotBlank
private String itemName;

@NotNull
@Range(min=1000, max=999999)
private Integer price;

@NotNull
@Max(9999)
private Integer quantity;

検証順序


各フィールドでタイプ
  • @ModelAttributeを変換してみます
    1)成功後
    2)失敗した場合はtypemismatchを使用してFielError
  • を追加
    アプリケーション
  • Validator
    バインディングに成功したフィールドのみbean Validation
  • を適用
    BenValidatorはバインドに失敗したフィールドにBenValidationを適用しません.
    考えてみれば、BenValidationを適用するのは、タイプ変換に成功し、バインドに成功したフィールドだけです.(モデルオブジェクトにバインドされた値が正常に戻ると、検証も意味があります.)

    BenValidationメッセージの検索順序


    生成されたメッセージコード順にメッセージソース内でメッセージ
  • を検索する
  • プレゼンテーションのメッセージ属性@NotBlank(message="空白!")
  • を使用
  • ライブラリが提供するデフォルト値は空にできません.
  • BenValidation Group(コンテキスト内のオブジェクトを使用)


    機能に基づいてグループを作成しbean検証を適用

    1.グループインタフェースの作成

    public interface SaveCheck {
    }
    

    2.bean検証でグループを設定する

     @NotNull(groups = UpdateCheck.class)
    private Long id;
    
    @NotBlank(groups = {SaveCheck.class, UpdateCheck.class})
    private String itemName;

    3.コントローラにグループを設定する


    public String editV2(@PathVariable Long itemId, @Validated(UpdateCheck.class) @ModelAttribute Item item, BindingResult bindingResult)
    public String addItemV2(@Validated(SaveCheck.class) @ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
    グループ機能は実務ではあまり使いにくい.これは、登録、変更などの機能が他のコマンドオブジェクトとして使用されるため、画面の使用がほとんど異なり、グループ設定が複雑であるためです.

    Validationタイプ固有のオブジェクトを使用する(グループではなく機能固有のdtoを使用する)


    1.機能駆動のDTO(Form…など)の作成

    @Data
    public class ItemSaveForm {
    
        private Long id;
    
        @NotBlank
        private String itemName;
    
        @NotNull
        @Range(min=1000, max=1000000)
        private Integer price;
    
        @NotNull
        @Max(value = 9999)
        private Integer quantity;
    
    }

    2.Controller Validationの変更

    public String addItem(@Validated @ModelAttribute("item") ItemSaveForm form, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {..
    @ModelAttribute("item") ItemSaveForm form
    ->(item)はモデルの名前です.追加しない場合は、オブジェクト名(最初の小文字の開始:itemSaveForm)がデフォルトです.
    したがって、目的のモデル名がある場合は、上記の手順に従って設定します.
    :htmlにitemモデルとして書き込まれているため、変更を最小限に抑えるために名前を設定します.

    HTTPメッセージ変換器


    @ModelAttribute vs @RequestBody


    HTTPリクエストパリテーブルを扱う@ModelAttributeは各フィールド単位で詳細に適用されます.したがって、特定のフィールドでタイプが一致しないエラーが発生しても、残りのフィールドは正常に処理されます.
    HttpMessageConverterは@ModelAttributeとは異なり、各フィールド単位ではなく、オブジェクト全体単位で適用されます.
    したがって、@Validおよび@Validatedは、メッセージ変換器が正常に実行され、Itemオブジェクトが作成された場合にのみ適用されます.
    @ModelAttributeは、フィールド単位で正確にバインドされます.特定のフィールドがバインドされていなくても、残りのフィールドは正常にバインドされ、Validatorを使用して検証することもできます.
    @RequestBody HttpMessageConverterフェーズでJSONデータをオブジェクトに変更できない場合、後続のステップ自体は行われず、異常が発生します.コントローラは呼び出されず、Validatorも適用されません.
    HttpMessageConverterフェーズ(オブジェクト化要求)に失敗すると、例外が発生します.Validationの前にエラーが発生しました.