スポンサーリンク

Webアプリケーション開発

リクエストのバリデーション・単項目チェック(SpringBoot)

投稿日:2021年2月11日 更新日:

バリデーションで単項目チェックをするパターン

Noリクエストのバリデーション方法とタイミング
1即座に400BadRequest
ハンドラメソッド内に入ってくる前に400とする。
2ハンドラメソッド内の任意タイミングでバリデーション結果を判定する。
3任意のタイミングでバリデーションを実行し、結果を得る。

パターン1 即座に400BadRequest

リクエスト値にアノテーションをつける

@Data
public class PostRequest {
    @NotBlank
    private String bookName;
    private String bookNameKana;
    private Integer price;
}

ハンドラメソッドに@validatedアノテーションを付与する

    @PostMapping
    public PostResponse post(@Validated @RequestBody PostRequest request) {
    ・・・
    }

@Validatedの代わりに、javax.validationの@Validを付与しても、同じ動きになります。

400 BadRequestエラーが返却されるようになる

ハンドラメソッドに@validatedアノテーションを付与すると、バリデーションルールに反した場合は400 BadRequestが返却されるようになります。

フロントでもバリデーションを行っている場合、APIに不正な値がリクエストされることは普通に使っていると起きえないので、この方法がハンドラメソッドがシンプルになる(コード行数が減る)ので良いです。

パターン2 ハンドラメソッド内の任意タイミングでバリデーション結果を判定する。

    @PostMapping
    public Mem01PostResponse post(@RequestBody @Validated Mem01PostRequest request, BindingResult bindingResult){
        if(bindingResult.hasErrors()) {
            return 任意のレスポンス
        }

ハンドラメソッドの引数に、「BindingResult bindingResult」を加えることで、BindingResultの中にバリデーション結果が格納されてきます。

エラーが1つでもある場合は、「BindingResult#hasErrors()」がtrueを返すので、任意のタイミングで判定し、任意のレスポンスを返すことができます。

エラーメッセージがBindingResultに格納されているので、レスポンスとしてエラーメッセージも返却したい場合はこの方法を使う必要があります。

パターン3 任意のタイミングでバリデーションを実行し、結果を得る。

パターン3はハンドラメソッドやサービスなど、ロジック内の任意のタイミングでバリデーションチェックを実行する方法です。

場合によっては、コントローラーのメソッドには入ってきて欲しい。メソッドの中でバリデーションチェックをしたいという場合もあります。

    @Autowired private SmartValidator smartValidator;

    @PostMapping
    public Mem01PostResponse post(@RequestBody Mem01PostRequest request, BindingResult bindingResult){
        smartValidator.validate(request, bindingResult);
        if(bindingResult.hasErrors()) {
            return // 任意のレスポンス
        }

ハンドラメソッドの@Validatedは削除し、BindingResult bindingResultを受け取るようにします。

SmartValidator#validateに、チェック対象(チェックアノテーションを付与したフィールドを持つクラス)とチェック結果を格納するBindingResultを渡すことで、BindingResultにチェック結果が格納されます。

後はパターン2同様に「BindingResult#hasErrors()」等を使って、任意のレスポンスを返すことができます。

用意されているバリデーション用のアノテーション

SpringBootで標準で使用できるアノテーションは2種類があります。

  • BeanValidationのビルトインアノテーション・・・Java標準のアノテーション群。javax.validation.constraintsに含まれる。
  • Hibernate Validatorが提供するアノテーション・・・org.hibernate.validator.constraintsに含まれる。
No
1@NotNull(javax.validation.constraints)
nullではないこと
2@NotBlank(javax.validation.constraints)
nullではない かつ空白スペースではない1文字以上であること
3

これらのアノテーションを利用するためには、build.gradleの依存関係に
implementation 'org.springframework.boot:spring-boot-starter-validation' を追記する必要があります。

>>独自のバリデーション用アノテーションを実装する方法はこちら

@Validatedと@Validの違いは?

本ページでは@Validatedを使用しました。似たアノテーションに@Validがありますが、結論はvalidation groupを使うなら、@Validatedを使う必要がある。それ以外に違いはありません。

ここでは両者の違いをまとめます。

@ValidatedのJavadoc

Variant of JSR-303's javax.validation.Valid, supporting the specification of validation groups. Designed for convenient use with Spring's JSR-303 support but not JSR-303 specific.
Can be used e.g. with Spring MVC handler methods arguments. Supported through org.springframework.validation.SmartValidator's validation hint concept, with validation group classes acting as hint objects.

org.springframework.validation.annotation.Validated

下記のようなことが書いています。
@Validとの違いは、validation groupsをサポートしていることです。
・SpringMVCのハンドラーメソッド(=コントローラーのメソッド)での使用を想定しています。

@ValidのJavadoc

Marks a property, method parameter or method return type for validation cascading.
Constraints defined on the object and its properties are be validated when the property, method parameter or method return type is validated.
This behavior is applied recursively.

javax.validation.Valid

下記のようなことが書いています。

Udemyのハンズオン動画講座でSpringBootのスキルを磨く!

スポンサーリンク

-Webアプリケーション開発

Copyright© 【Spring Hack】 , 2022 All Rights Reserved Powered by AFFINGER5.