Spring Boot中如何接收不含Map字段名的请求体?
实现根层级Map字段的请求体接收
方法一:使用@JsonAnySetter注解(推荐)
通过Jackson的@JsonAnySetter注解,可以自动将请求体根层级中未匹配到明确字段的所有键值对,映射到指定的Map属性中,完美适配你的需求。
修改ExampleObject的定义如下:
import com.fasterxml.jackson.annotation.JsonAnySetter import com.fasterxml.jackson.annotation.JsonProperty class ExampleObject( @JsonProperty("paramTwo") val paramTwo: String ) { val paramOne: MutableMap<String, Int> = mutableMapOf() @JsonAnySetter fun setParamOne(key: String, value: Int) { paramOne[key] = value } }
说明
@JsonAnySetter标记的方法会拦截所有未匹配到paramTwo的键值对,将键和对应Int值存入paramOne集合。- 原Controller方法无需修改,依然可以正常接收请求:
@PostMapping("/test") fun postTestFunction(@RequestBody data: ExampleObject) { // 直接使用data.paramOne(存储根层级的所有额外键值对)和data.paramTwo }
测试请求体
{ "test": 1, "customKey": 3, "paramTwo": "test" }
方法二:自定义Jackson反序列化器
如果需要更复杂的解析逻辑,可以自定义反序列化器手动处理JSON结构:
- 编写自定义反序列化器:
import com.fasterxml.jackson.core.JsonParser import com.fasterxml.jackson.databind.DeserializationContext import com.fasterxml.jackson.databind.JsonDeserializer import com.fasterxml.jackson.databind.JsonNode class ExampleObjectDeserializer : JsonDeserializer<ExampleObject>() { override fun deserialize(p: JsonParser, ctxt: DeserializationContext): ExampleObject { val node = p.codec.readTree<JsonNode>(p) val paramTwo = node.get("paramTwo").asText() val paramOne = mutableMapOf<String, Int>() // 遍历所有节点,排除paramTwo后存入Map node.fields().forEach { entry -> if (entry.key != "paramTwo") { paramOne[entry.key] = entry.value.asInt() } } return ExampleObject(paramOne, paramTwo) } }
- 在
ExampleObject上指定使用该反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize @JsonDeserialize(using = ExampleObjectDeserializer::class) class ExampleObject( val paramOne: Map<String, Int>, val paramTwo: String )
- Controller方法保持不变即可。
内容的提问来源于stack exchange,提问作者krown_loki
相关产品推荐
相关产品推荐

