如何通过Spring Boot API调用提取嵌套JSON值并按类别过滤
解决JsonPath提取嵌套列表并按Category过滤的问题
问题背景
从Controller接口拿到的JSON数据如下:
[ { "id": 1, "footwearList": [ { "id": 1, "name": "sandals", "category": "men" }, { "id": 3, "name": "sandals", "category": "women" } ], "clothingList": [ { "id": 1, "name": "t-shirt", "category": "men" }, { "id": 3, "name": "tshirt", "category": "women" } ] }, { "id": 2, "footwearList": [ { "id": 2, "name": "shoes", "category": "men" }, { "id": 4, "name": "shoes", "category": "women" } ], "clothingList": [ { "id": 2, "name": "shirt", "category": "men" }, { "id": 4, "name": "shirt", "category": "women" } ] } ]
已添加JsonPath依赖:
<dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> <version>2.7.0</version> </dependency>
但使用以下代码提取数据失败:
public List<Store> getCategory(){ List<Store> footwear = JsonPath.read(json, "$..footwear"); }
问题原因
代码里的JsonPath表达式写错了——JSON中的列表字段是footwearList,但表达式用了$..footwear,路径不匹配导致提取不到数据。
解决方案
1. 正确提取嵌套列表数据
要获取所有footwearList或clothingList,修改JsonPath表达式为对应字段名:
- 提取所有鞋类列表:
$..footwearList - 提取所有服装列表:
$..clothingList
如果要映射到自定义实体类,先定义对应类:
// 鞋类实体 public class Footwear { private Integer id; private String name; private String category; // 构造方法、getter/setter省略 } // 服装实体 public class Clothing { private Integer id; private String name; private String category; // 构造方法、getter/setter省略 }
然后用泛型读取数据:
// 提取所有鞋类数据,合并为一个List List<Footwear> allFootwear = JsonPath.read(json, "$..footwearList[*]", new TypeRef<List<Footwear>>() {}); // 提取所有服装数据 List<Clothing> allClothing = JsonPath.read(json, "$..clothingList[*]", new TypeRef<List<Clothing>>() {});
2. 按Category过滤数据
有两种过滤方式:
方式一:用JsonPath表达式直接过滤
直接在表达式中指定category条件,返回符合要求的数据:
// 提取所有男性鞋类 List<Footwear> menFootwear = JsonPath.read(json, "$..footwearList[?(@.category == 'men')]", new TypeRef<List<Footwear>>() {}); // 提取所有女性服装 List<Clothing> womenClothing = JsonPath.read(json, "$..clothingList[?(@.category == 'women')]", new TypeRef<List<Clothing>>() {});
方式二:提取后在Java代码中过滤
如果需要更复杂的过滤逻辑,先提取所有数据再用Stream过滤:
List<Footwear> allFootwear = JsonPath.read(json, "$..footwearList[*]", new TypeRef<List<Footwear>>() {}); // 过滤男性鞋类 List<Footwear> menFootwear = allFootwear.stream() .filter(item -> "men".equals(item.getCategory())) .collect(Collectors.toList());
完整示例代码
import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.TypeRef; import java.util.List; import java.util.stream.Collectors; public class JsonPathDemo { public static void main(String[] args) { String json = "你的JSON字符串"; // 提取并过滤男性鞋类 List<Footwear> menFootwear = JsonPath.read(json, "$..footwearList[?(@.category == 'men')]", new TypeRef<List<Footwear>>() {}); // 提取所有服装后过滤女性款 List<Clothing> allClothing = JsonPath.read(json, "$..clothingList[*]", new TypeRef<List<Clothing>>() {}); List<Clothing> womenClothing = allClothing.stream() .filter(c -> "women".equals(c.getCategory())) .collect(Collectors.toList()); } } class Footwear { private Integer id; private String name; private String category; // getter和setter public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } } class Clothing { private Integer id; private String name; private String category; // getter和setter public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
内容的提问来源于stack exchange,提问作者NJ42
相关产品推荐
相关产品推荐

