簡體   English   中英

Kotlin Spring 引導 bean 驗證不起作用

[英]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)

output: 在此處輸入圖像描述

該問題已在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM