Kotlin对象中@RequestBody搭配@Valid未触发空/空白字符串字段校验问题
问题根因
当前出现注解仅能拦截null值、不拦截空字符串/纯空格的现象,核心有两个原因:
- 校验注解未正确绑定到Kotlin类的可扫描字段上:你观察到的"@NotBlank仅对null生效"是假象,null拦截是Kotlin非空类型在JSON解析阶段触发的,@NotBlank因为绑定位置错误,根本没有被校验引擎加载,自然不会触发空串、纯空格的拦截逻辑
- 嵌套对象、集合的级联校验链路未打通,校验逻辑只停留在最外层的BumblebeeEventList类,不会递归进入嵌套结构做字段校验
分步修正操作
- 确保引入基础校验依赖
Spring Boot项目需引入spring-boot-starter-validation,缺包会导致校验引擎的注解规则加载不完整,仅保留基础非空判断能力。 - 修正Kotlin类的注解绑定规则
Kotlin构造器参数上的注解默认绑定到构造函数参数本身,Bean Validation引擎只会扫描类字段、getter方法上的注解,因此必须通过use-site指定注解的绑定目标为字段,否则@NotBlank、@NotEmpty这类字符串规则不会被引擎识别。
实体类调整为:class Event( @field:NotBlank val localTime: String ) class BumblebeeEvent( @field:NotNull @field:Valid val event: Event ) class BumblebeeEventList( @field:NotNull @field:Valid val events: List<BumblebeeEvent> ) - 打通级联校验链路
给集合字段、嵌套对象字段加上@Valid注解,确保校验逻辑会递归进入集合的每一个元素、以及嵌套对象的内部字段,不会只停留在最外层类的校验。 - 修正控制器代码的编译问题
控制器层入参旁的@Valid注解保留即可,需修正原代码中未定义的变量引用,保证逻辑可正常运行:@Controller class BumblebeeEventController { @PostMapping("/publish") fun eventIntake(@RequestBody @Valid payload: BumblebeeEventList) : ResponseEntity<String>{ return ResponseEntity("Published ${payload.events.size} event(s) successfully", HttpStatus.OK) } }
调整后的校验覆盖说明
修正完成后所有需求规则会全部生效:
- 请求体整体非null:@RequestBody解析逻辑+最外层@Valid触发机制保障
- 集合字段非null:events字段上的@NotNull规则正常校验
- 集合内嵌套的BumblebeeEvent对象非null:级联校验触发每个元素上的@NotNull规则
- 单字段全量校验:@NotBlank会同时拦截null值、空字符串、纯空格字符串,符合校验要求
注意:如果出现纯空格不被拦截的情况,检查Hibernate Validator版本,6.0及以上版本的@NotBlank默认会对字符串做首尾空格裁剪后判断长度,可直接满足纯空格拦截的需求。
内容的提问来源于stack exchange,提问作者Mee
相关产品推荐
相关产品推荐

