You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin数据类结合SpringBoot Validation校验Null失效,如何解决?

Kotlin + SpringBoot Validation 非空校验失效问题解决

问题场景

定义了如下Kotlin数据类,使用@NotNull做非空校验:

data class GetSourceListRequest(   
    @NotNull(message = "category not allow null")
    val category: List<Int>    
)

通过@ControllerAdvice处理异常:

@ExceptionHandler(value = [HttpMessageNotReadableException::class])
fun <T> httpMessageNotReadableExceptionHandler(e: HttpMessageNotReadableException): String {          
    return e.message
}

当请求JSON中缺失category字段时,得到的错误信息是:

JSON parse error: Instantiation of [simple type, class com.sage.feature.source.database.request.GetSourceListRequest] value failed for JSON property category due to missing (therefore NULL) value for creator parameter category which is a non-nullable type

自定义的@NotNull注解未生效,因为Jackson在JSON反序列化环节先抛出了异常,跳过了Spring Validation校验流程。

解决方案

1. 配置Jackson允许缺失构造参数

Kotlin数据类的非空构造参数,Jackson默认会在缺失对应JSON字段时直接抛异常。需要关闭这个特性,让Jackson将缺失字段设为null,再交给Validation校验。

方式一:通过配置文件

在application.yml中添加:

spring:
  jackson:
    deserialization:
      fail-on-missing-creator-properties: false

方式二:通过配置类

@Configuration
class JacksonConfig {
    @Bean
    fun jackson2ObjectMapperBuilderCustomizer(): Jackson2ObjectMapperBuilderCustomizer {
        return Jackson2ObjectMapperBuilderCustomizer { builder ->
            builder.failOnMissingCreatorProperties(false)
        }
    }
}

2. 开启Controller层的Validation校验

在Controller的请求参数上添加@Valid或@Validated注解,触发校验流程:

@PostMapping("/source/list")
fun getSourceList(@RequestBody @Valid request: GetSourceListRequest): ResponseEntity<Any> {
    // 业务逻辑处理
    return ResponseEntity.ok().build()
}

3. 扩展异常处理器,捕获Validation异常

添加MethodArgumentNotValidException的处理器,返回自定义的校验错误信息:

@ControllerAdvice
class GlobalExceptionHandler {
    @ExceptionHandler(HttpMessageNotReadableException::class)
    fun handleHttpMessageNotReadable(e: HttpMessageNotReadableException): ResponseEntity<Map<String, String>> {
        return ResponseEntity.badRequest()
            .body(mapOf("error" to "JSON格式解析错误"))
    }

    @ExceptionHandler(MethodArgumentNotValidException::class)
    fun handleValidationError(e: MethodArgumentNotValidException): ResponseEntity<Map<String, String>> {
        val errorMap = e.bindingResult.allErrors.associate {
            val fieldError = it as FieldError
            fieldError.field to fieldError.defaultMessage.orEmpty()
        }
        return ResponseEntity.badRequest().body(errorMap)
    }
}

此时当请求缺失category字段时,会触发@NotNull校验,返回{"category": "category not allow null"}的错误响应。

内容的提问来源于stack exchange,提问作者SageJustus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:05:24