[英]Post API using Spring Boot returns null values for nested json
[英]How to extract nested json values by using spring boot api call
我有以下 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"
}
]
}
]
从 controller 的 api 调用中获取此 json,并希望从 json 到 881290284135988 从 controller 调用中获取嵌套值,例如(footwearlist,clothinglist)。如果找到,则通过过滤类别再次获取。
我尝试在 pom.xml 中使用添加了依赖项的 JsonPath
依赖:
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.7.0</version>
</dependency>
试图获取嵌套的 json 但没有成功。
public List<Store> getCategory(){
List<Store> footwear = JsonPath.read(json, "$..footwear");
}
不需要引入新的依赖,有几种可能的方法可以使用 Jackson 解决这个问题。
如果出于某种原因,您不想将所有数据具体化为对象并希望对其进行迭代。 然后使用ObjectMapper.readTree()
从您的 JSON 生成一个JsonNode
,并检查每个嵌套节点的字段名称。 为此,您可以使用JsonNode.fields()
。 如果遇到匹配字段 - 获取数据。
要检查字段是否匹配,您可以使用正则表达式。 这是基于正则表达式的谓词,它会检查给定的字符串是否包含 substring "footwear"
:
public static final Predicate<String> FOOTWEAR = Pattern.compile("footwear").asPredicate();
这就是迭代具有您显示的结构的树的代码可能如下所示:
String json = // incoming JSON
ObjectMapper mapper = new ObjectMapper();
List<Item> items = StreamSupport.stream(mapper.readTree(json).spliterator(), false)
.<JsonNode>mapMulti((node, consumer) ->
node.fields().forEachRemaining(entry -> {
if (FOOTWEAR.test(entry.getKey())) entry.getValue().forEach(consumer);
})
)
.map(StreamingNestedObjects::nodeToItem)
.toList();
items.forEach(System.out::println);
Output:
Item{id=1, name='sandals', category='men'}
Item{id=3, name='sandals', category='women'}
Item{id=2, name='shoes', category='men'}
Item{id=4, name='shoes', category='women'}
假设Item
class 如下所示:
public class Item {
private int id;
private String name;
private String category;
// getters, setters, etc.
}
但是传入的 JSON 不是很大,我建议使用 Jackson 的数据绑定。
考虑以下 class Store
:
public class Store {
private int id;
private Map<String, List<Item>> items = new HashMap<>();
@JsonAnySetter
public void readStore(String key, List<Item> value) {
items.put(key, value);
}
@JsonAnyGetter
public Map<String, List<Item>> writeStore(String key, List<Item> value) {
return items;
}
// no-args constructor, getter and setter for id property, etc.
}
它的一个属性是 map 类型的Map<String, List<Item>>
包含项目列表。 这个 map 可以通过@JsonAnySetter
和@JsonAnyGetter
序列化/反序列化。
那就是如何将传入的 JSON 解析为Store
实例列表:
ObjectMapper mapper = new ObjectMapper();
List<Store> stores = mapper.readValue(json, new TypeReference<>() {});
然后遍历列表,检查地图的键并选择您需要的商店。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.