[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 {}
バリデーショングループの実行制御について、以下で図としてまとめられている。