Spring Boot单值JSON请求报错:如何正确定义单值数据类?
问题原因及解决方案
问题根源
你遇到的是Kotlin单属性嵌套数据类在Spring Boot 3.x Jackson序列化机制下的兼容问题:
- Spring Boot 3.x配套的Jackson版本,对Kotlin单属性嵌套类的反序列化逻辑存在限制,无法自动识别单参数构造函数作为反序列化入口;
- 当添加可选参数后,数据类变为多属性结构,Jackson能正常匹配构造函数,因此反序列化恢复正常。
正确的单值数据类写法(按优先级推荐)
1. 将嵌套数据类改为顶级类
把EchoActionInput、EchoActionRequestBody、EchoActionOutput移到EchoAction类外部作为顶级类,Jackson无需处理嵌套类的特殊逻辑,可直接识别构造函数:
package io.company.connectors.fauxservice.actions import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RestController data class EchoActionOutput(val content: String) data class EchoActionInput(val text: String) data class EchoActionRequestBody(val inputs: EchoActionInput) @RestController class EchoAction { @PostMapping("/fauxservice/actions/echo/execute") fun execute(@RequestBody body: EchoActionRequestBody): EchoActionOutput { return EchoActionOutput(body.inputs.text) } }
2. 给单属性添加@field:JsonProperty注解
如果必须保留嵌套类结构,给数据类的构造函数参数添加@field:JsonProperty注解,明确告知Jackson字段映射关系:
@RestController class EchoAction { data class EchoActionOutput( @field:JsonProperty("content") val content: String, ) data class EchoActionInput( @field:JsonProperty("text") val text: String, ) data class EchoActionRequestBody( @field:JsonProperty("inputs") val inputs: EchoActionInput, ) @PostMapping("/fauxservice/actions/echo/execute") fun execute(@RequestBody body: EchoActionRequestBody): EchoActionOutput { return EchoActionOutput(body.inputs.text) } }
3. 给属性设置默认值(仅临时方案,不推荐)
给单属性设置默认值,让Kotlin生成无参构造函数,适配Jackson默认反序列化逻辑:
data class EchoActionInput(val text: String = "") data class EchoActionRequestBody(val inputs: EchoActionInput = EchoActionInput())
注意:这种方式会改变数据类语义(允许空文本或默认实例),仅适合特殊场景。
额外说明
Spring Boot默认已引入jackson-module-kotlin依赖,负责处理Kotlin类的序列化/反序列化,但单属性嵌套类的场景需要额外处理,上述两种推荐方案可彻底解决问题。
内容的提问来源于stack exchange,提问作者szedjani
相关产品推荐
相关产品推荐

