Spring Bootのアノテーションによるバリデーションを、任意の値に対して行う方法

こんにちは。 エキサイト株式会社の三浦です。

こちらは、エキサイトホールディングス Advent Calendar 2023の11日目の記事になります。

qiita.com

良ければ他の記事もどうぞ!

さて、Spring Bootでは、アノテーションを使ってクラス内の特定のフィールドに対してバリデーションを掛けることができます。

今回は、そのアノテーションによるバリデーションを、クラスのフィールドに限らず任意の値に掛ける方法を紹介します。

アノテーションによるバリデーション

Spring Bootでは、Controllerにおいて、アノテーションを使って以下のように値にバリデーションを掛けることができます。

package sample.controller;

import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping
public class SampleController {

    @GetMapping("sample")
    public String sample(@Validated @ModelAttribute SampleClass sampleClass) {
        return "sample_page";
    }

    @Data
    public static class SampleClass {
        @NotBlank
        private String sampleField;
    }
}

今回は、 sampleField が空白だとバリデーションで弾かれる、というものです。

結果は以下のようになります。

/sample へのアクセス時

/sample?sampleField=aa へのアクセス時

このように、Controllerであれば非常に簡単にアノテーションを掛けることができるのですが、では任意の値にこのアノテーションの内容でバリデーションを掛けるにはどうすれば良いのでしょうか?

任意の値に、アノテーションを使ったバリデーションを掛ける方法

任意の値にバリデーションを掛ける際は、少々手順としては迂回が入りますが、それでも難しい方法ではありません。

package sample.controller;

import jakarta.validation.Validator;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping
@RequiredArgsConstructor
public class SampleController {
    // 自分のタイミングでバリデーションを行えるバリデータ
    private final Validator validator;

    @GetMapping("sample")
    public String sample() {
        final String validateText = "";

        if (!this.isValid(validateText)) {
            throw new RuntimeException("invalid");
        }

        return "sample_page";
    }

    public Boolean isValid(String sampleField) {
        final SampleClass sampleClass = new SampleClass();
        sampleClass.setSampleField(sampleField);

        return validator
                .validate(sampleClass)
                .isEmpty();
    }

    @Data
    public static class SampleClass {
        @NotBlank
        private String sampleField;
    }
}

Spring Bootでは、 Validator という、先程Controllerの引数で自動的に行なっていたバリデーションを任意のタイミングで実行できる機能が存在します。

それを使って、好きなタイミングでバリデーションを行うだけです。

  1. バリデーション用のクラスを作る
  2. バリデーション用のクラスにバリデーションを掛けたいデータを入れる
  3. バリデーションを実行する

のように、一度データをクラスに詰めるということはしなくてはいけませんが、それでもそこまで大した手間なくアノテーションのバリデーションを任意の値に掛けることができるようになりました。

validateText に空白文字を入れた場合

ここではControllerのクラスで実行していますが、もちろんController以外でも使用可能です。

最後に

空白文字のバリデーションくらいであればアノテーション以外でも適切なバリデーション方法はあるでしょうが、複雑なバリデーションや、アノテーションでしか実装されていないバリデーションなどがある場合はこういった方法が有効な場面もあるでしょう。

そのような場合にぜひ活用してみてください!