如何让Java程序按需解析单个Simple对象或List<Simple>并保留原JSON格式?
解决方案
针对你的需求——既支持解析单个Simple对象或Simple数组,又能在序列化时保留原格式(单个对象输出为JSON对象,数组输出为JSON数组),可以通过以下两种方式实现:
方式一:手动判断JSON节点类型解析
先将JSON字符串解析为JsonNode,判断目标字段的节点类型后再分别处理,这种方式直观且灵活:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.List; public class ParserDemo { private static final ObjectMapper objectMapper = new ObjectMapper(); public static void main(String[] args) throws Exception { // 场景1:数组输入解析为List<Simple> String arrayJson = "{\"simple\" : [ {\"name\":\"a\", \"email\" : \"a@z.com\"}, {\"name\":\"b\", \"email\" : \"b@z.com\"} ]}"; JsonNode arrayNode = objectMapper.readTree(arrayJson).get("simple"); if (arrayNode.isArray()) { List<Simple> simpleList = objectMapper.convertValue( arrayNode, objectMapper.getTypeFactory().constructCollectionType(List.class, Simple.class) ); System.out.println("解析结果:" + simpleList); } // 场景2:单个对象输入解析为Simple String objectJson = "{\"simple\" : {\"name\":\"c\", \"email\" : \"c@z.com\"} }"; JsonNode objectNode = objectMapper.readTree(objectJson).get("simple"); if (objectNode.isObject()) { Simple simple = objectMapper.convertValue(objectNode, Simple.class); System.out.println("解析结果:" + simple); } } }
序列化时直接根据对象类型输出即可,ObjectMapper会自动识别并输出对应格式:
import java.util.Arrays; import java.util.Map; // 序列化单个Simple对象 Simple simple = new Simple("c", "c@z.com"); String singleJson = objectMapper.writeValueAsString(Map.of("simple", simple)); // 输出:{"simple":{"name":"c","email":"c@z.com"}} // 序列化List<Simple> List<Simple> list = Arrays.asList(new Simple("a", "a@z.com"), new Simple("b", "b@z.com")); String arrayJson = objectMapper.writeValueAsString(Map.of("simple", list)); // 输出:{"simple":[{"name":"a","email":"a@z.com"},{"name":"b","email":"b@z.com"}]}
方式二:自定义反序列化器(适用于包装类场景)
如果你的业务需要通过包装类统一接收参数,可以给包装类的字段自定义反序列化器,实现自动适配单个对象或数组:
1. 定义包装类
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; class SimpleWrapper { @JsonDeserialize(using = SimpleListOrObjectDeserializer.class) private Object simple; // 实际类型为Simple或List<Simple> // getter、setter public Object getSimple() { return simple; } public void setSimple(Object simple) { this.simple = simple; } }
2. 实现自定义反序列化器
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 com.fasterxml.jackson.databind.type.CollectionType; import java.io.IOException; import java.util.List; public class SimpleListOrObjectDeserializer extends JsonDeserializer<Object> { private static final ObjectMapper mapper = new ObjectMapper(); private static final CollectionType LIST_TYPE = mapper.getTypeFactory().constructCollectionType(List.class, Simple.class); @Override public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode node = p.getCodec().readTree(p); if (node.isArray()) { return mapper.readValue(node.traverse(), LIST_TYPE); } else if (node.isObject()) { return mapper.readValue(node.traverse(), Simple.class); } throw new IllegalArgumentException("Unsupported JSON type for 'simple' field"); } }
3. 使用示例
public class WrapperDemo { private static final ObjectMapper objectMapper = new ObjectMapper(); public static void main(String[] args) throws Exception { // 解析数组输入 String arrayJson = "{\"simple\" : [ {\"name\":\"a\", \"email\" : \"a@z.com\"}, {\"name\":\"b\", \"email\" : \"b@z.com\"} ]}"; SimpleWrapper arrayWrapper = objectMapper.readValue(arrayJson, SimpleWrapper.class); System.out.println("数组解析结果类型: " + arrayWrapper.getSimple().getClass()); // 输出class java.util.ArrayList // 解析单个对象输入 String objectJson = "{\"simple\" : {\"name\":\"c\", \"email\" : \"c@z.com\"} }"; SimpleWrapper objectWrapper = objectMapper.readValue(objectJson, SimpleWrapper.class); System.out.println("对象解析结果类型: " + objectWrapper.getSimple().getClass()); // 输出class Simple } }
序列化包装类时,ObjectMapper会根据simple字段的实际类型自动输出对应格式,不会将单个对象转为数组。
内容的提问来源于stack exchange,提问作者axnet
相关产品推荐
相关产品推荐

