繁体   English   中英

自定义Spring注释未调用

[英]Custom Spring annotation not called

在我的Spring Boot项目中,我创建了一个自定义注释,其中验证器扩展了ConstraintValidator以验证RequestBody中的某些字段。 注释适用于非嵌套字段,但不会为嵌套字段调用验证器。

我的注释看起来像:

@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.RUNTIME)
@Constraint(validatedBy = [CustomValidator::class])
@Suppress("unused")
@MustBeDocumented
annotation class CustomValidation(
    val message: String = "validation failed",
    val groups: Array<KClass<*>> = [],
    val payload: Array<KClass<out Payload>> = []
)

我的验证员类:

@Component
class CustomValidator : ConstraintValidator<CustomValidation, String> {

    override fun isValid(field: String?, context: ConstraintValidatorContext?): Boolean {
        if (field != "example") {
            return false
        }
        return true
    }
}

它适用于以下情况:

data class MyRequest(
// validator works perfectly here
    @JsonProperty("example") @CustomValidation val example: String? = null,
    @JsonProperty("locale") val locale: String? = null
)

但是当放在嵌套对象上时,不会调用验证器:

data class MyRequest(
    @JsonProperty("nested") val nested: NestedClass? = null,
    @JsonProperty("locale") val locale: String? = null
)

data class NestedClass(
// validator not called in that case
@JsonProperty("example") @CustomValidation val example: String? = null
)

用法MyRequest在我的班级RestController

@PostMapping("/endpoint")
    fun doSomething(
        @Valid @RequestBody myRequest: MyRequest,
        @RequestHeader(value = "token") token: String
    ): ResponseEntity<MyResponse> = ResponseEntity.ok(myService.getData(myRequest))

关于如何解决这个问题的任何想法? 我已经尝试将@Valid注释放在nested字段上,但它仍然不起作用

通常,要在嵌套类中进行验证,您需要使用与@Valid相同的嵌套类类型来注释父类的字段。

在这里,验证对工作NestedClass类,你需要添加@Validnested的领域MyRequest类。 因为它是构造函数的一部分,所以应该使用Annotation Use-site Targets来完成,如下所示:

data class MyRequest(
    @field:Valid @JsonProperty("nested") val nested: NestedClass? = null,
    @JsonProperty("locale") val locale: String? = null
)

@CustomValidation注释在不使用use-site目标的情况下工作的原因是因为它只有一个使用@Target(AnnotationTarget.FIELD)定义的目标,而@Valid注释有多个可能的目标,即@Target(value={METHOD,FIELD,CONSTRUCTOR,PARAMETER}) ,因此您需要使用use-site目标来告诉编译器正确的目标。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM