🐤
【Spring Boot(kotlin)】バリデーションを自作する
はじめに
KotlinのAnnotationsを読んでいて、annotation classを使って何かアウトプットしたいと思いこの記事を書いています。
日本の電話番号のフォーマットをチェックするためのカスタムバリデーションを作成してみました。
作成したもの
@MustBeDocumented
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
@Constraint(validatedBy = [JapanesePhoneNumberValidator::class])
annotation class JapanesePhoneNumber(
val message: String = "有効な日本の電話番号ではありません", // エラーメッセージ
val groups: Array<KClass<*>> = [], // バリデーションをグループ化する際に使用
val payload: Array<KClass<out Payload>> = [] // バリデーションの追加情報(エラーレベルなど)を指定する際に使用
)
class JapanesePhoneNumberValidator : ConstraintValidator<JapanesePhoneNumber, String> {
override fun isValid(value: String?, context: ConstraintValidatorContext?): Boolean {
if (value == null) return true
return value.matches(Regex("^0[789]0-[0-9]{4}-[0-9]{4}$"))
}
}
使用例
@JapanesePhoneNumber
val phoneNumber: String
解説
アノテーションクラス
@Target
- どこにアノテーションを付与するかを決める
-
AnnotationTarget.CLASS
やAnnotationTarget.FUNCTION
など様々な指定ができます(10種類以上あります)
@Retention
- アノテーションがどのタイミングまで保持されるかを指定できる
claudeに聞いてみた結果
AnnotationRetention.SOURCE // ソースコードレベルでのみ保持(コンパイル時に破棄)
AnnotationRetention.BINARY // コンパイルされたクラスファイルまで保持(リフレクションでは参照不可)
AnnotationRetention.RUNTIME // 実行時まで保持(リフレクションで参照可能)
@Constraint
- validatedByにバリデーションロジックを実装したクラスの指定ができる
バリデーションクラス
JapanesePhoneNumberValidator
- ConstraintValidatorというinterfaceのisValidをオーバーライドすることで、その中にバリデーションロジックを書くことができる
まとめ
SpringBootで開発しているとjakartaやHibernateのバリデーションを使用することが多いと思うのですが、特殊なフォーマットチェックなどが必要な場合は、カスタムバリデーションを自作することで柔軟に対応できることやアノテーションクラスについても学びが得られました。
(今回は正規表現だけで済むシンプルなケースだったので、自作せずとも@Pattern
でも対応はできると思います)
余談
今回は正規表現で携帯電話番号のフォーマットチェックを実装しましたが、もっと正確に電話番号バリデーションかけたい場合はgoogleが出しているlibphonenumberというライブラリがあるので、それを使っても良いのかなと思いました。
Discussion