数値判定や文字列の文字数判定など、リクエストの中身をチェックする際は Spring Boot の @Validated アノテーションに任せて、data class のフィールドごとに個別にチェックをしています。
例えば文字数の最大が 20 文字列の場合はこんな感じ。
1 | @get:Size(max = 20) |
単体の項目チェックならこれで事足りるのですが、複数項目のバリデーションチェックを行おうと思うと、別途カスタムバリデーション用のクラスを用意しないといけません。
今回は相関チェックと、マルチバイトを含んだ文字数について紹介したいと思います。
相関チェック
何も考えなければ、ロジック内で if 文 1 個書いて済ませたくなっちゃうところですが、そんなことは許されない時代。
小回りがきく PHP でも、フレームワークのルールに乗っかればカスタムバリデーション用のクラスを定義するのが一般的ですしね。
しかし Spring Boot のカスタムバリデーションは、アノテーション登場しまくりでちょっぴり面倒です。
まずはアノテーションクラスの作成から。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import javax.validation.Constraint import javax.validation.Payload import kotlin.reflect.KClass @MustBeDocumented @Constraint(validatedBy = [HogeValidator::class]) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.FIELD, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.VALUE_PARAMETER) @Retention(AnnotationRetention.RUNTIME) annotation class Hoge( val message: String = “{hoge.message}", val groups: Array<KClass<*>> = [], val payload: Array<KClass<out Payload>> = [] ) |
今回は 2 つの項目の合計の文字数が規定の文字数をオーバーしていないかチェックしたいと思います。
チェックの実装はこんなイメージ。
when の中で参照する HogeRequest はリクエストの data class を想定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import javax.validation.ConstraintValidator import javax.validation.ConstraintValidatorContext class HogeValidator : ConstraintValidator<Hoge, Any> { private val limitLen: Int = 5 override fun isValid(value: Any?, context: ConstraintValidatorContext?): Boolean = value?.let { return when (it) { is HogeRequest -> { val strlen1 = it.str1?.length ?: 0 val strlen2 = it.str2?.length ?: 0 (strlen1 + strlen2 <= limitLen) } else -> false } } ?: false } |
最後に、チェックしたいフィールドを定義している data class に @Hoge のアノテーションを付けておきます。
文字数の判定
今回は文字数を数えるのに String クラスの length プロパティを参照します。
何となく String クラスには length() のようなメソッドが用意されているイメージだったのですがプロパティになります。
ちなみに、マルチバイトを含む文字列の場合、文字数が返ってくるのかバイト数が返ってくるのか初めて使う言語の場合は迷いますよね。
Kotlin の String クラスの length プロパティの場合は文字数になります。
「アイウエオ」のマルチバイト文字の場合は 5 ですね。
PHP の場合だと mb_strlen() の結果と同じです。
まとめ
相関チェックと文字列の文字数判定について紹介しました。
些細なことでも、初めての言語やフレームワークを触ると未知数なものが意外と多いです。
慣れた言語やフレームワークなら、最初の頃は 10 倍以上は生産性も違ってくると思います。
だから早く慣れていくことが大切ですね。