I was trying to write a custom annotation to validate a field in a Micronaut project, I came across this section in their documentation Defining Additional Constraints
My understanding was that is completely possible to write my own annotation to validate a field in my POJO but after trying for hours, I can't get my validation to work, it simply does not get invoked, could it be I'm missing something fundamental about the way how Micronaut works?
Annotation
@Retention(RUNTIME)
@Constraint(validatedBy = [])
annotation class FieldValidator(
val message: String = "invalid format ({validatedValue})"
)
Factory
@Factory
class ValidatorFactory {
@Singleton
fun fieldPatternValidator(): ConstraintValidator<FieldValidator, CharSequence> {
return ConstraintValidator { value, annotation, context ->
context.messageTemplate("invalid format ({validatedValue}), should be test")
value == "test"
}
}
}
Filter
@Introspected
data class HelloWorldFilter(
@FieldValidator
val field: String?
)
Controller
@Controller("/hello")
open class HelloController() {
@Get("{?filters*}")
@Produces(MediaType.TEXT_PLAIN)
open fun index(@Valid filters: HelloWorldFilter): String {
return filters.toString()
}
}
I have a small demo on Github, to reproduce
run ./gradlew run
call http://localhost:8080/hello?field=abc
that expected behaviour should be bad request since the field is matching the desired value.
Using your demo project, I changed your HelloWorldFilter
class to
@Introspected
data class HelloWorldFilter(
@field:FieldValidator
val field: String?
)
Ran it, then:
curl "http://localhost:8080/hello?field=abc"
Output was as you expect:
{"message":"Bad Request","_embedded":{"errors":[{"message":"filters.field: invalid format (abc), should be test"}]},"_links":{"self":{"href":"/hello?field=abc","templated":false}}}
With:
curl "http://localhost:8080/hello?field=test"
Output:
HelloWorldFilter(field=test)