如何用Jackson仅反序列化JSON的dishes字段?解决匹配异常
解决Jackson反序列化嵌套JSON数组的问题
首先咱们先揪出报错的核心原因:你的Dish类里把details字段定义成了List<Detail>,但看你提供的JSON结构,每个菜品的details是单个对象(比如{"toppings": ["cheese", "tomato", "tuna"], "price": 10}),根本不是数组!Jackson尝试把单个对象解析成ArrayList,可不就抛出MismatchedInputException嘛。
第一步:修正实体类定义
先把Dish类里的details类型改对,从List<Detail>改成Detail,匹配JSON的结构:
public class Dish { @JsonProperty("name") private String name; @JsonProperty("details") private Detail details; // 改为单个Detail对象,而非List } public class Detail { @JsonProperty("toppings") private List<String> toppings; @JsonProperty("price") private int price; @JsonProperty("inOffer") private boolean inOffer; }
第二步:两种正确的反序列化实现
你原本的思路没问题,修正类之后就可以正常运行,另外再给你一种更简洁的写法:
方式一:提取JsonNode再反序列化(你的思路优化)
ObjectMapper mapper = new ObjectMapper(); // 忽略无关字段的配置已经很合理 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 读取整个JSON,定位到dishes节点 JsonNode dishesNode = mapper.readTree(json).path("dishes"); // 构造List<Dish>的类型 CollectionType dishListType = TypeFactory.defaultInstance() .constructCollectionType(List.class, Dish.class); // 反序列化节点为目标列表 List<Dish> dishes = mapper.readerFor(dishListType).readValue(dishesNode);
方式二:用JsonPointer直接定位(更简洁)
Jackson支持通过JsonPointer直接跳转到目标字段,一步完成反序列化:
ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 直接定位到/dishes路径,反序列化为List<Dish> List<Dish> dishes = mapper.readValue( json, TypeFactory.defaultInstance().constructCollectionType(List.class, Dish.class), JsonPointer.compile("/dishes") );
补充说明
- 如果你确实需要
details是数组,那得修改JSON格式,把每个details改成数组形式(比如"details": [{"toppings": [...], "price": 10}]),但根据你提供的JSON,显然不需要这么做。 - 你配置的
FAIL_ON_UNKNOWN_PROPERTIES已经完美帮你忽略了foo和foo2这些无关字段,无需额外处理它们。
内容的提问来源于stack exchange,提问作者neza
相关产品推荐
相关产品推荐

