👻

BeanValidation on SpringBoot

2021/08/11に公開

ためした環境

  • SpringBoot 1.3.5
  • Java 8

基本

FORM のフィールドにアノテーションをつけると、自動的にバリデーションを
行ってくれる。SpringBoot の場合は、Controller の BindingResult に結果が入る。

MyForm.java">
// lombok使ってると思ってください
@Data
public class MyForm {
    @NotNull
    String value;
}

単項目チェックはこれで十分。javax.constraints に用意されているだけでも

結構な数のバリデータがそろっているので割といける。

https://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html

独自のバリデーションを作りたい場合も案外難しくはない。そう、単項目チェックならね。

複合チェック

バリデータをがんばって作ればできるらしいので頑張る。
…がそんなのは忘れるので応用のパターン使えばよいのではないか

応用

BeanValidation のチェック対象は、フィールドだけではなく、メソッドの返り値もチェックできる。以下は例

MyForm.java
@Data
public class MyForm {
    String value;

    @AssertTrue
    public boolean isValueNotNull() {
        return (value != null);
    }
}

エラーメッセージは異なるが、value == null の時検証エラーになる。(NotNull と同条件)

ということは、これで複数のフィールドにまたがるチェックを行うと話が早いだろう。

注意事項としては、getter と同じルールのメソッド名にしないとチェックされない。

本気でハマるので注意。

エラーメッセージ

普通に BeanValidation を使うと、エラーメッセージがかなりシステム寄りのものになる。

それではいろいろと困る場合(ほとんど困る)メッセージリソースに以下のように記述する。

messageResource.properties
AssertTrue.myForm.value = カスタムエラーです。

みたいな形で書くと各 form ごとにメッセージを変えられる。

中の動きを想像してみる

検証対象クラス内の public メソッドを抽出する

→getter として正しくないメソッドは捨てる(返り値の型含めて)

boolean & isMyMethod() は OK。 boolean でなければ get ~である必要がある。

→ それぞれのメソッドごとに、アノテーションを探す。メソッドについていればその検証
→ getter ぽいメソッド名からフィールド名を算出して、そのフィールドにアノテーションがあれば検証。
みたいな動きしているのかなーと妄想。(ソース見ればいいんだけれども)

チェック用アノテーションがついていても、getter として正しくない返り値と、メソッド名の
組み合わせの場合、無視されるので大体あっているのではないか。

TODO

記事内のソースがあってるかテストする

Discussion