Spring Boot Rest Controller中如何将JSON数组映射为单个对象
解决方案:将JSON数组的第一个元素映射到单个POJO属性
当然可以实现!你只需要借助Jackson的序列化/反序列化能力,通过两种常见方式就能把JSON中的imp数组第一个元素绑定到RtbRequest的单个Imp属性上,下面是具体方案:
方案一:自定义Jackson反序列化器(灵活通用)
这种方式适合需要处理复杂逻辑的场景,比如同时兼容数组和单个对象的情况,或者后续需要调整选择规则的需求。
1. 编写自定义反序列化器
创建一个继承自JsonDeserializer的类,专门处理数组转单个对象的逻辑:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; public class ImpListToSingleImpDeserializer extends JsonDeserializer<Imp> { @Override public Imp deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { ObjectMapper mapper = (ObjectMapper) p.getCodec(); JsonNode node = p.readValueAsTree(); // 处理数组:取第一个元素;处理单个对象:直接解析;空数组返回null if (node.isArray() && node.size() > 0) { return mapper.treeToValue(node.get(0), Imp.class); } else if (node.isObject()) { return mapper.treeToValue(node, Imp.class); } return null; } }
2. 在POJO字段上添加注解
修改RtbRequest类的imp字段,指定使用上面的反序列化器:
@JsonInclude(JsonInclude.Include.NON_NULL) public class RtbRequest { // 其他属性... @JsonDeserialize(using = ImpListToSingleImpDeserializer.class) private Imp imp; public void setImp(Imp imp) { this.imp = imp; } // 对应getter方法... }
方案二:修改Setter方法(简洁快速)
如果业务逻辑只是简单取数组第一个元素,这种方式无需额外类,直接利用Jackson的自动绑定特性即可。
修改RtbRequest的setImp方法,让它接收List<Imp>类型参数,然后在方法内取第一个元素赋值:
@JsonInclude(JsonInclude.Include.NON_NULL) public class RtbRequest { // 其他属性... private Imp imp; // Jackson会自动将JSON数组绑定到List<Imp>参数 public void setImp(List<Imp> impList) { if (impList != null && !impList.isEmpty()) { this.imp = impList.get(0); } // 空数组场景可根据业务需求选择赋值null或抛出异常 } // 对应getter方法... }
两种方案对比
- 方案一:灵活性更高,支持同时兼容数组和单个对象的JSON结构,后续调整选择规则(比如取第二个元素、按条件筛选)也更方便。
- 方案二:代码量更少,实现快速,适合只需要取第一个元素的简单场景。
两种方案都能完美适配你提供的JSON结构,解析后RtbRequest的imp属性会自动绑定数组中第一个id=1的Imp对象。
内容的提问来源于stack exchange,提问作者Nabeel Ahmed




