当前位置: 首页 > 知识库问答 >
问题:

kotlin:无法获取验证api的注释

商正诚
2023-03-14

==========更新==========

当我将注释更改为@get: NotNull、@get: Min和@get: Max时,hibernate验证器可以成功读取这些注释。

但我仍然想知道的是:

为什么验证api的注释,例如@NotNull、@Min和@Max不能直接用于数据类的成员,而JPA的注释可以????

==========贝娄是起源问题===========

当我试图在数据类上使用validation-api的注释时,Validator类(来自hibernate-validator)无法获得注释,所以验证失败了。

我写了一个测试用例,其中包括3个数据类:

  • 第一个使用JPA注释@Colpillar和@Id,可以通过测试用例成功读取。
  • 第二个在成员上使用validation-api注释@Notempty、@Min、@Max,这些注释不能被测试用例读取
  • 第三个使用validation-api注释@get: Notempty,@get: Min,@get: Max,测试用例无法读取这些注释。

@Column、@NotNull、@Min和@Max的目标和保留都是:运行时和字段

那么,后面发生了什么?如何正确使用验证注释?

下面是测试用例:

import org.hibernate.validator.constraints.NotEmpty
import org.junit.Test
import javax.persistence.Column
import javax.persistence.Id
import javax.validation.constraints.Max
import javax.validation.constraints.Min
import kotlin.reflect.KFunction
import kotlin.reflect.KProperty
import kotlin.reflect.jvm.javaField
import kotlin.reflect.jvm.javaMethod

class KotlinFeatureTest2 {
    @Test
    fun test_get_annotation() {
        // can get field's annotation for BeanUseJPAAnnotation success
        println("Getting field annotations for BeanUseJPAAnnotation :")
        BeanUseJPAAnnotation::class.members.forEach {
            if (it is KProperty) {
                val field = it.javaField
                println("${field?.name}'s annotations:")
                field?.annotations?.forEachIndexed { i, an ->
                    println("        $i is: $an")
                }
            }
        }

        println("--------------------")
        println("Getting field annotations for BeanUseValidationAnnotation :")
        // CANT get field's annotation for BeanUseJPAAnnotation success
        BeanUseValidationAnnotation::class.members.forEach {
            if (it is KProperty) {
                val field = it.javaField
                println("${field?.name}'s annotations:")
                field?.annotations?.forEachIndexed { i, an ->
                    println("        $i is: $an")
                }
            }
        }

        println("--------------------")
        println("Getting field annotations for BeanUseValidationAnnotationOnMethod :")
        // CANT get field's annotation for BeanUseJPAAnnotation success
        BeanUseValidationAnnotationOnMethod::class.members.forEach {
            if (it is KFunction) {
                val method = it.javaMethod
                println("${method?.name}'s annotations: ")
                method?.annotations?.forEachIndexed { i, an ->
                    println("        $i is: $an")
                }
            }
        }
    }
}

data class BeanUseJPAAnnotation(
        @Column(name = "id") @Id val id: String,
        @Column(name = "user_name") val name: String)

data class BeanUseValidationAnnotation(
        @NotEmpty(message = "name can not be empty")
        val name: String,

        @Min(value = 1)
        @Max(value = 100)
        val age: Int
)

data class BeanUseValidationAnnotationOnMethod(
        @get:NotEmpty(message = "name can not be empty")
        val name: String,

        @get:Min(value = 1)
        @get:Max(value = 100)
        val age: Int)

这是这个测试用例的输出:

Getting field annotations for BeanUseJPAAnnotation :
id's annotations:
    0 is: @javax.persistence.Column(nullable=true, unique=false, precision=0, name=id, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true)
    1 is: @javax.persistence.Id()
name's annotations:
    0 is: @javax.persistence.Column(nullable=true, unique=false, precision=0, name=user_name, length=255, scale=0, updatable=true, columnDefinition=, table=, insertable=true)
--------------------
Getting field annotations for BeanUseValidationAnnotation :
age's annotations:
name's annotations:
--------------------
Getting field annotations for BeanUseValidationAnnotationOnMethod :
component1's annotations: 
component2's annotations: 
copy's annotations: 
equals's annotations: 
hashCode's annotations: 
toString's annotations: 

共有1个答案

魏晨
2023-03-14

以下是< code > javax . persistence . column 的签名部分:

@Target({METHOD, FIELD}) 
@Retention(RUNTIME)
public @interface Column {

相反,这里是javax.validation.contractions.Min的相同部分:

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
@Documented
@Constraint(validatedBy = { })
public @interface Min {

正如您可以看到的那样,JPA Persistence注释的目标是METHODFIELD,因此Kotlin将它们放在 PARAMETER 。假设在为构造函数声明的属性生成注释时,Kotlin编译器只选择注释参数。Java中的BeanUseValidationAnnotation构造函数签名等效项如下所示:

public BeanUseValidationAnnotation(@NotEmpty(message = "name can not be empty") @NotNull String name, @Min(1L) @Max(100L) int age) {

此行为在留档中说明:

如果未指定使用站点目标,则会根据正在使用的注释的@Target注释来选择目标。如果有多个适用的目标,则使用以下列表中的第一个适用目标:

    < li> param < li> 属性 < li > <代码>字段
 类似资料:
  • 我有一个简单的登录模型类,几乎没有数据注释验证 View是一个部分View,如下所示: 我相信我已经做了验证消息显示所需的所有事情,但它没有,客户端验证也没有。在母版页的头部区域,我还包括了以下脚本 是什么导致了这个问题?解决办法是什么?

  • 我有一个使用javax注释的jax-rs项目(

  • 接口说明 获取验证码 如需调用,请访问 开发者文档 来查看详细的接口使用说明 该接口仅开放给已获取SDK的开发者 API地址 POST /api/server/1.0.0/getValidCode 是否需要登录 否 请求字段说明 无 响应字段说明 无 响应成功示例 {} 响应失败示例 {} 响应接受类型 image/jpeg;charset=UTF-8 响应状态码 HTTP状态码 原因 204 N

  • 我正在尝试使用python从web获取数据。我导入了urllib。请求包,但在执行时,我得到错误: 我正在Mac OS High Sierra上使用Python 3.7 当我将URL更改为“http”时,我能够获取数据。但是,我相信,这可以避免检查SSL证书。 因此,我在互联网上查找并找到了一个解决方案:运行 这解决了我的问题。但是我对SSL之类的东西一无所知。你能帮我理解它到底做了什么来解决我的

  • 我将按照本指南使用Gupshup whatsapp https://www.Gupshup.io/developer/docs/bot-platform/guide/gupshup-bot-library-for-node构建NodejS bot 不确定这里出了什么问题。请告诉我如何解决这个问题?

  • 我一直在尝试使用nativescript创建一个android应用程序。我正在使用fetch模块从服务器获取响应。当我试图从httpbin获得响应时。org/get,没关系。但当我试图从本地服务器获取响应时,网络请求失败。错误 发送到httpbin。组织/获取- 发送到本地主机:8000/api- 当我尝试从纯节点中的localhost:8000/api获取响应时。js通过请求模块。它工作得很好。