[英]Kotlin Spring Boot bean validation not working
I have quite a few projects that is slowly being migrated from Java to Kotlin, but I'm facing a problem when changing from Java POJO to Kotlin data classes. 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)
和 gradle:
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
,但沒有任何效果。 I see many others have the same problem and using a Java class from a Kotlin REST controller works. 更改為非數據 class 也可以進行驗證。 任何人都知道是否可以使用 Kotlin 數據類進行 bean 驗證?
不要使用數據 class 進行驗證
當您使用數據 class 時,您需要在注釋之前添加 @field:{} ,或者您可以在沒有數據 class 的情況下使用 class。
數據 class:
class AuthorInput(
@field:NotBlank @field:Size(max = 20, min = 3) val first_name: String? = null,
@field:NotBlank @field:Size(max = 20, min = 3) val last_name: String? = null,
@field:NotEmpty val role: List< String?>? = null
){
}
僅 class:
class AuthorInput {
@NotBlank
@Size(max = 20, min = 3)
val first_name: String? = null
@NotBlank
@Size(max = 20, min = 3)
val last_name: String? = null
@NotEmpty
val role: List<@NotBlank String?>? = null
}
我認為您只是缺少 controller class 頂部的 @Validated 注釋。
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import javax.validation.Valid
import javax.validation.constraints.NotEmpty
@SpringBootApplication
class BootValidationApplication
fun main(args: Array<String>) {
runApplication<BootValidationApplication>(*args)
}
@RestController
@RequestMapping("/api/v1")
@Validated
class CustomerController {
@PostMapping("/customer")
fun createCustomer(@Valid @RequestBody customer: Customer) {
println(customer)
}
}
data class Customer(@field:NotEmpty val name: String)
該問題已在 Kotlin 版本 1.6.10 中得到修復。 https://github.com/JetBrains/kotlin/releases/tag/v1.6.10 。 升級后的異常現在是org.springframework.web.bind.MethodArgumentNotValidException
。
使字段可以為空,即使它不是,然后添加 @field:NotNull
數據 class 測試(@field:NotNull val id: String?)
這將停止 kotlin 驗證在 javax 之前發生
您必須先添加 @get:Valid 。 例如:
data class Location(
@get:Valid @get:DecimalMin("-90") @get:DecimalMax("90") val lat: Double,
@get:Valid @get:DecimalMin("-180") @get:DecimalMax("180") val lng: Double
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.