[Spring Boot] バリデーションに順番をつける
アノテーションによる Bean バリデーションチェックを順番に実行する方法。デフォルトだと、付与しているアノテーションのバリデーションチェックはすべて同時に実行される。これを @NotBlank チェックに通ったら、次に @Pattern(regexp=xxx) のチェックを実行、みたいにしたい。
@GroupSequence を使う
グルーピング用インターフェースを作る。
public class Groups {
public interface First {
}
public interface Second {
}
public interface Third {
}
}
バリデーショングループに @GroupSequence を付与
バリデーショングループに @GroupSequence で順番を指定する。
@GroupSequence({Default.class, First.class, Second.class, Third.class})
public interface MailSequence {
}
バリデーション対象の Bean
バリデーションしたいフィールドに、 グルーピング用インターフェースを指定する。
public class User {
@NotBlank
@Length(max = 20)
private String name;
@NotBlank(groups= UpdateSample.class)
@Size(min = 5, max = 128)
@Pattern(regexp=xxx, groups = First.class)
@CustomValidationA(groups = Second.class)
@CustomValidationB(groups = Third.class)
public String mail;
}
Controller
Controller に @GroupSequence を付与したグループを指定する。
@RestController
public class SampleController {
// ➀
@PostMapping
public void create(@Validated({MailSequence.class}) @RequestBody User user) {
// …
}
// ➁
@PutMapping
public void update(@Validated({UpdateSample.class, MailSequence.class}) @RequestBody User user) {
// …
}
}
バリデーションの動き
Controller① のパターン
@NotBlank 以外のバリデーションチェックが動く。
Controller➁ のパターン
すべてのバリデーションチェックが動く。
注意すべき動き@GroupSequence({Default.class, First.class, Second.class, Third.class}) のように Default.class を 1 番に指定しても、 Default.class と First.class のバリデーションチェックは同時に実施される。なので、ここでは、 @Size と @Pattern のバリデーションチェックは同じタイミングとなる。
Default.class に注意
Controller① のパターンDefault.class である @Size も動く。これは、@GroupSequence に Default.class を含めているため。@GroupSequence({First.class, Second.class, Third.class}) とすると、 Default.class の @Size バリデーションチェックは動かない。
Controller➁ のパターン
すべてのバリデーションチェックが動くのは、 UpdateSample に Default を継承しているため。 Default を継承していない場合には、 Default.class である @Size は動かない。
public static interface UpdateSample extends Default {}
バリデーショングループの実行制御について、以下で図としてまとめられている。
