- 履歴一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- Spring Boot/KotlinでCustom Validatorを作成する へ行く。
- 1 (2018-02-13 (火) 17:13:39)
- 2 (2018-02-13 (火) 17:44:09)
キーワード†
- Spring Boot
- Validation/Validator
- Kotlin
したいこと†
Kotlinでカスタム・バリデータを作成したい。
Javaでやるのと同じようにすればいいんだけど、Kotlinの文法的にちょっと躓いたのでメモ。
どうやって†
相関チェック:時間入力の前後チェックをしたいとして。
Period.kt†
package me.fukuchiharuki.example.validation.constraints
import me.fukuchiharuki.example.validation.PeriodValidator
import javax.validation.Constraint
import javax.validation.Payload
import kotlin.reflect.KClass
@Target(AnnotationTarget.CLASS, AnnotationTarget.FIELD, AnnotationTarget.ANNOTATION_CLASS)
@Retention(AnnotationRetention.RUNTIME)
@Constraint(validatedBy = [PeriodValidator::class])
annotation class Period(
val message: String = "{me.fukuchiharuki.example.validation.constraints.Period}",
val groups: Array<KClass<*>> = [],
val payload: Array<KClass<out Payload>> = [],
val startField: String = "start",
val endField: String = "end"
)
PeriodValidator.kt†
package me.fukuchiharuki.example.validation
import me.fukuchiharuki.example.validation.constraints.Period
import org.springframework.beans.BeanWrapperImpl
import java.time.LocalTime
import javax.validation.ConstraintValidator
import javax.validation.ConstraintValidatorContext
class PeriodValidator: ConstraintValidator<Period, Object> {
private var message: String = ""
private var startField: String = ""
private var endField: String = ""
override fun initialize(constraintAnnotation: Period?) {
if (constraintAnnotation === null) return
message = constraintAnnotation.message
startField = constraintAnnotation.startField
endField = constraintAnnotation.endField
}
override fun isValid(value: Object?, context: ConstraintValidatorContext?): Boolean {
val beanWrapper = BeanWrapperImpl(value)
val startTimeInput = beanWrapper.getPropertyValue(startField).toString()
val endTimeInput = beanWrapper.getPropertyValue(endField).toString()
if (チェックする(startTimeInput, endTimeInput)) return true
setContext(context!!)
return false
}
private fun setContext(context: ConstraintValidatorContext) {
context.disableDefaultConstraintViolation()
context.buildConstraintViolationWithTemplate(message)
.addPropertyNode(endField)
.addConstraintViolation()
}
}
ちなみに†
constraints.Periodはネストした子側のクラスのアノテーションにすることも、ネストした親側のプロパティのアノテーションにすることもできる。
- 子側のクラスのアノテーションにする場合
- 親側のプロパティのアノテーションには次を書いて
@field: Valid
- 子側のクラスのアノテーションに次を書く
@constraints.Period
- 親側のプロパティのアノテーションには次を書いて
- 親側のプロパティのアノテーションにする場合
- 親側のプロパティのアノテーションに次を書く
@constraints.Period
- 親側のプロパティのアノテーションに次を書く
親側のプロパティのアノテーションに書く場合、「@field:」が要らないのね、なんで?