Springのアノテーションを自作してみる
モチベーション
Springでアノテーションを自作してみます。
DTOなどでバリデーションを行う際に以下のような事を思いました。
- デフォルトのバリデーションでは物足りない
- でもControllerでより後ろの層でバリデーションを行うのは冗長
なによりも「アノテーションを作る」ってSpringを使いこなしてる感じがかっこよくないですか?
ということで作ってみます。
作成
今回はEmailの形式で入力されているかバリデーションを行うアノテーションを作成してみます。
(正規表現のみを使用しているので@regexを使えばいいのですが,ロマン大事😇)
手順は以下の通りです。
- アノテーション(@interface)を作成する
- アノテーションをつけた時,どんなバリデーションをするか決める実装クラスを作成
- アノテーションをつける!
基本的にはこのような流れで作成できました。
手順1: アノテーションクラス(@interface)を作成する
おそらくですがSpringで提供されているパッケージで基本的に作成できます。
@interface
をつけることで自分のカスタムしたアノテーションクラスを作成できます。
サンプルコードを以下に示します。
@Target({ElementType.FIELD}) // アノテーションをつけられる場所を指定
@Retention(RetentionPolicy.RUNTIME) // アノテーション情報が維持される範囲
@Constraint(validatedBy = SampleValidator.class) // 実行クラス
public @interface SampleAnotation {
// デフォルトのエラーメッセージ
String message() default "Invalid email";
// バリデーショングループ
Class<?>[] groups() default {};
// バリデーションペイロード
Class<? extends Payload>[] payload() default {};
}
基本的には以下のような情報を設定します。
- どこでバリデーションするのか(@Target)
- どの範囲で使うのか(@Retention)
- アノテーションをつけた時に実行したい処理はどこにあるか(@Constraint)
要するに,ここでは 「アノテーションをどのように使いたいか」 の設定を主にここで行えます。
今回自身が作成したアノテーションのコード
私は以下のようなアノテーションを作成しました。
今回は使用しませんでしたが上記で示した他にも以下のような設定ができます。
- バリデーショングループ
- バリデーションを実行するグループを決めることができます
- 「特定の場面のみバリデーションを実行したい!」ってときに使えます
- バリデーションペイロード
- バリデーションを実行する際に使用するペイロードを指定することができます。
- エラーメッセージ以外のデータを合わせて返す事ができるみたいです。
手順2: どんなバリデーションをするか決める実装クラスを作成
アノテーションをつけた時にどのようなバリデーションを行うかを決めるクラスを作成します。
このクラスはアノテーションクラスで指定した@Constraint
に設定したクラスです。
ここでは2つやる事があります。
-
ConstraintValidator<Annotation, T>インターフェースを実装します。
アノテーションクラス と 対象のデータの型 を指定して実装します。 -
バリデーションの内容を実装する
isValid
メソッドをオーバーライドします。
バリデーションしたいロジックをここに記述します。
public class SampleValidator implements ConstraintValidator<SampleAnotation, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return false;
}
}
今回自身が作成したバリデータのコード
今回はシンプルにメールアドレスの形式が正しいかチェックするバリデータを作成しました。
(正規表現でチェックしています。)
手順3: アノテーションをつける!
ここまででアノテーションとバリデータの作成が完了しました!
あとは使うのみです!
public class SampleDTO {
// 自作アノテーションをつける
@CustomEmail
private String email;
}
使用
実際に動かしてみてみましょう。
アノテーションのターゲットを変えたり,フィールド変数を定義して値を受け取るようなアノテーションを作成してみたり…
クラスにつける事で日付の前後関係をチェックしたり(開催日と終了日)など色々作れそうですね!
まとめ
今回はSpringのアノテーションを自作してみました。
いつか有益なバリデーションを作成したら公開してみたい…ッ!
Discussion