Я пытался написать пользовательскую аннотацию для проверки поля в проекте Micronaut, я наткнулся на этот раздел в их документации Определение дополнительных ограничений
Насколько я понимаю, вполне возможно написать свою собственную аннотацию для проверки поля в моем POJO, но после нескольких часов попыток я не могу заставить свою проверку работать, она просто не вызывается, может быть, я что-то упустил основные сведения о том, как работает Micronaut?
Аннотация
@Retention(RUNTIME)
@Constraint(validatedBy = [])
annotation class FieldValidator(
val message: String = "invalid format ({validatedValue})"
)
Фабрика
@Factory
class ValidatorFactory {
@Singleton
fun fieldPatternValidator(): ConstraintValidator<FieldValidator, CharSequence> {
return ConstraintValidator { value, annotation, context ->
context.messageTemplate("invalid format ({validatedValue}), should be test")
value == "test"
}
}
}
Фильтр
@Introspected
data class HelloWorldFilter(
@FieldValidator
val field: String?
)
Контроллер
@Controller("/hello")
open class HelloController() {
@Get("{?filters*}")
@Produces(MediaType.TEXT_PLAIN)
open fun index(@Valid filters: HelloWorldFilter): String {
return filters.toString()
}
}
У меня есть небольшая демка на Github, чтобы воспроизвести
беги ./gradlew run
вызовите http://localhost:8080/hello?field=abc
, что ожидаемое поведение должно быть неверным запросом, поскольку поле соответствует желаемому значению.
Извините, вы правы, я забыл добавить шаг, в основном это запуск службы и вызов конечной точки hello world, я добавлю шаги завтра!
@ShingJo Я пробовал, это уже не проблема.
Используя ваш демонстрационный проект, я изменил ваш класс HelloWorldFilter
на
@Introspected
data class HelloWorldFilter(
@field:FieldValidator
val field: String?
)
Запустил, затем:
curl "http://localhost:8080/hello?field=abc"
Вывод был таким, как вы ожидаете:
{"message":"Bad Request","_embedded":{"errors":[{"message":"filters.field: invalid format (abc), should be test"}]},"_links":{"self":{"href":"/hello?field=abc","templated":false}}}
С:
curl "http://localhost:8080/hello?field=test"
Выход:
HelloWorldFilter(field=test)
Интересно, это работало, я думаю, что версия, которая у меня была запущена локально, не имела @Valid (я, вероятно, удалил его, потому что думал, что это не нужно), вы правы, похоже @field:FieldValidator
Я буду читать о том, почему мне нужно его объявить например, @NotNull отлично работает, спасибо!
Поскольку в вашей демонстрации нет ни теста, ни шагов для воспроизведения проблемы. Единственное, что выделяется, это:
@FieldValidator val field: String?
обычно с Kotlin это@field:FieldValidator
.