Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

1K
Visualizações
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 validation stops working in REST controllers. I have created a very simple project directly from https://start.spring.io to demonstrate the failure.

@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)

and 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"
    }
} 

Sending a request does not trigger the bean validation, but it throws a HttpMessageNotReadableException because id is NULL.

curl -X POST http://localhost:8080 -H "Content-Type: application/json" -d "{}"

I have tried both @Valid and @Validated and using @get:NotNull on the attributes, but nothing works. I see many others have the same problem and using a Java class from a Kotlin REST controller works. Also changing to a non data class makes validation works. Anyone know if it's possible to get bean validation working with Kotlin data classes?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

The issue has been fixed in Kotlin version 1.6.10. https://github.com/JetBrains/kotlin/releases/tag/v1.6.10. After upgrading the exception is now org.springframework.web.bind.MethodArgumentNotValidException.

over 4 years ago · Santiago Trujillo Relatório

0

Make the field nullable even its not, and then add @field:NotNull

data class Test(@field:NotNull val id: String?) 

This will stop kotlin validation to happen before javax

over 4 years ago · Santiago Trujillo Relatório

0

I think you are just missing @Validated annotation on top of your controller class.

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.validation.FieldError
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.MethodArgumentNotValidException
import org.springframework.web.bind.annotation.*
import org.springframework.web.context.request.WebRequest
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler
import java.time.LocalDateTime
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): ResponseEntity<Customer> {
        return ResponseEntity.ok(customer)
    }
}


@ControllerAdvice
class CustomerExceptionHandler : ResponseEntityExceptionHandler() {

    override fun handleMethodArgumentNotValid(
        ex: MethodArgumentNotValidException,
        headers: HttpHeaders,
        status: HttpStatus,
        request: WebRequest
    ): ResponseEntity<Any> {

        val fieldErrors: List<FieldError> = ex.fieldErrors
        val errorMapping = fieldErrors.associate { it.field to it.defaultMessage }

        val errorDetails = ErrorDetails(
            timestamp = LocalDateTime.now(),
            message = "Validation Failed",
            details = errorMapping
        )
        return ResponseEntity(errorDetails, HttpStatus.BAD_REQUEST)
    }
}

data class Customer(
    @field:NotEmpty(message = "Mandatory field: Name is missing in Request Body") val name: String
)

data class ErrorDetails(val timestamp: LocalDateTime, val message: String, val details: Map<String, String?>)

The output should look something like this enter image description here

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda