Spring动态反序列化JSON:兼容单个对象与数组格式问题
解决JSON中单个对象/数组兼容的反序列化问题
针对接口返回的Relation字段既可能是单个对象、也可能是对象数组的情况,提供以下几种修复方案:
方案1:全局开启Jackson自动转换特性
通过配置ObjectMapper的ACCEPT_SINGLE_VALUE_AS_ARRAY特性,Jackson会自动将单个对象视为长度为1的数组处理,无需修改实体类代码。
ObjectMapper objectMapper = new ObjectMapper(); // 开启单个值转数组的特性 objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY); // 反序列化示例 String json = "..."; // 接口返回的JSON字符串 MainClass result = objectMapper.readValue(json, MainClass.class);
方案2:自定义字段反序列化器(局部生效)
如果不想全局修改配置,可以为relation字段自定义反序列化逻辑,仅针对该字段处理单个对象/数组的兼容。
步骤1:实现自定义反序列化器
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 java.io.IOException; import java.util.ArrayList; import java.util.List; public class SingleOrListDeserializer<T> extends JsonDeserializer<List<T>> { private final Class<T> elementType; public SingleOrListDeserializer(Class<T> elementType) { this.elementType = elementType; } @Override public List<T> deserialize(JsonParser parser, DeserializationContext context) throws IOException { JsonNode node = parser.getCodec().readTree(parser); List<T> resultList = new ArrayList<>(); if (node.isArray()) { // 处理数组格式 for (JsonNode itemNode : node) { resultList.add(parser.getCodec().treeToValue(itemNode, elementType)); } } else if (node.isObject()) { // 处理单个对象格式 resultList.add(parser.getCodec().treeToValue(node, elementType)); } return resultList; } }
步骤2:在实体类字段上添加注解
修改MainClass的relation字段,指定使用自定义反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; public record MainClass( @JsonProperty("Relation") @JsonDeserialize(using = SingleOrListDeserializer.class, contentAs = Relation.class) List<Relation> relation ) {}
额外注意:字段匹配问题
你的Relation实体类中定义了String relation,但接口返回的JSON里对应的字段是url,这会导致该字段反序列化后为null。需要修正Relation的定义:
public record Relation( String url, String Id ) {}
内容的提问来源于stack exchange,提问作者RedBlue
相关产品推荐
相关产品推荐

