スポンサーリンク

Webアプリケーション開発

独自アノテーションを作成する

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

実案件では、Bean ValidationとHibernateValidatorで用意されているバリデーションだけでは不十分なことが多いです。そこで、独自にバリデーション用のアノテーションを作成します。

独自のバリデーション用アノテーションを作成する2つの方法

  1. 既存のアノテーションを合成して作成する
  2. チェックロジックを独自に実装する(完全に独自アノテーション)

多くの場合は、正規表現でアノテーションを作成するため、1の方法を推奨します。1の方が作成するクラスが1つ減るためシンプルです。

【推奨】既存のアノテーションを合成して作成する

Bean Validationの仕組みを利用して、アノテーションを実装することができます。下記は、全角ひらがなのチェック用アノテーションです。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
@Constraint(validatedBy = {})
@ReportAsSingleViolation
@Pattern(regexp = "[\u3041-\u3096]*")
public @interface Hiragana {

    String message() default "ひらがなで入力してください";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };

    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    public @interface List {
        Hiragana[] value();
    }
}

6行目の@Patternでjavax.validation.constraintsを合成しています。正規表現だけひらがなに変えているだけです。これだけで、下記のようにDTOで使用できます。

@Data
public class Mem01PostRequest {
    @NotBlank
    private String nameSei;
    @Hiragana
    private String kanaSei;
}
Noアノテーション意味・値
1@Retentionアノテーションで付加された情報がどの段階まで保持されるかを定義
RetentionPolicy.RUNTIME/CLASS/SOURCE
2@Targetアノテーションを付与できる対象を指定
ElementType. TYPE/METHOD/FIELD/PARAMETER
3@Documented
4@ConstraintBean Validationの仕組みを利用することを宣言する。
#initialize と #isValid を定義する。
5@ReportAsSingleViolationString message() default で指定したメッセージを使用することを表す。省略すると、親アノテーションのメッセージになる。
6@Pattern正規表現でチェックすることを表すアノテーション。
バリデーションを作成するときに使うアノテーション

メッセージのカスタマイズ方法

固定メッセージをプロパティファイルから取得する

Bean Validationの仕組みを利用した場合、validationMessages.propertiesにメッセージを定義する決まりです。下記の要領です。

// 省略
public @interface Hiragana {

    String message() default "{validation.Hiragana.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };

    // 省略
}

波カッコの中にメッセージのキーを指定します。

validation.Hiragana.message=ひらがなで入力してください。

プロパティファイルにキー=メッセージの形式で記述します。

validationMessages.properties は プロジェクトルート/src/main/resorces 配下に配置します。

固定メッセージに項目名を埋め込む

現場ではさらに「○○は○○で入力してください」のように、項目名も求められることが多いです。項目名を表示しないと、ユーザは「どの項目のこと?」と迷ってしまい不親切です。

// 省略
public @interface Hiragana {
    String fieldName();
    String message() default "{validation.Hiragana.message}";
    // 省略
}

バリデーションのアノテーションにfieldNameを追加します。表示する名前を保持できるようにします。
※filedNameという名前でなくても良いです。name/valueなど何でも良いです。

@Data
public class Mem01PostRequest {
    @NotBlank
    private String nameSei;
    @Hiragana(fieldName = "かな性")
    private String kanaSei;
}

アノテーションの引数に、fieldNameを追加して表示する名前を与えます。

validation.Hiragana.message={fieldName}はひらがなで入力してください。

メッセージにはこのように埋め込むことができます。

チェックロジックを独自に実装する

作成するのは2つです。

  • アノテーションを定義するインターフェース
  • バリデーションロジックを定義するクラス

アノテーションを定義するインターフェース

アノテーション自体を@interfaceを用いて定義します。

バリデーションロジックを定義するクラス

ConstraintValidator<アノテーションクラス, バリデーション対象の型>を指定する。

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

スポンサーリンク

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

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