【发布时间】:2022-01-09 21:44:21
【问题描述】:
我有很多项目正在慢慢地从 Java 迁移到 Kotlin,但是在从 Java POJO 更改为 Kotlin 数据类时遇到了问题。 Bean 验证在 REST 控制器中停止工作。我直接从https://start.spring.io 创建了一个非常简单的项目来演示失败。
@SpringBootApplication
class RestValidationApplication
fun main(args: Array<String>) {
runApplication<RestValidationApplication>(*args)
}
@RestController
class Controller {
@PostMapping
fun test(@Valid @RequestBody request: Test) {
println(request)
}
}
data class Test(@field:NotNull val id: String)
和毕业:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.6.1"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.6.0"
kotlin("plugin.spring") version "1.6.0"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
}
}
发送请求不会触发 bean 验证,但会抛出 HttpMessageNotReadableException,因为 id 为 NULL。
curl -X POST http://localhost:8080 -H "Content-Type: application/json" -d "{}"
我尝试了@Valid 和@Validated 并在属性上使用@get:NotNull,但没有任何效果。我看到许多其他人也有同样的问题,并且使用 Kotlin REST 控制器中的 Java 类可以工作。
更改为非数据类也可以进行验证。任何人都知道是否可以使用 Kotlin 数据类进行 bean 验证?
【问题讨论】:
-
我可能错了,但是控制器类可能也应该用
@Validated注解... -
它应该按原样工作。您是否尝试过使用 Spring Boot 2.5.X 或添加
hibernate-validator依赖项? -
我已经尝试过 Spring boot
2.4.13、2.5.7和2.6.1。还尝试将org.springframework.boot:spring-boot-starter-validation替换为org.hibernate.validator:hibernate-validator:7.0.1.Final。当然还有 Kotlin1.5.x和1.6.0。 -
你试过其他Java版本吗?
-
@NotNull(假设这是 JSR-303 之一)实际上不是在为数据类生成的构造函数中创建null检查吗?这基本上会在构造时抛出错误,这根本不允许进行验证,因为它会在过程的早期失败。请在发生这种情况时在您获得的服务器上添加完整的堆栈跟踪,因为我认为它在对象构造时失败,这基本上会停止整个处理(这也解释了为什么它可以在常规 java 类上工作)。
标签: java spring spring-boot kotlin