我有一个JSON以下,我需要从中创建一个Map<String, String>
。在下面的JSON中,我只有三个parentCategory
级别,但一般来说它可以更多或有时可以更少。
79720
,id
部分为categories
,其值应为10987
,id
为parentCategory
。 }。 现在我可以在其中嵌套parentCategory
,因此我遇到了为此制作POJO的问题。我可以有一个级别parentCategory
,或者我可以在每个parentCategory
内嵌套parentCategory
,我总是需要获取最后一个parentCategory
的ID。
所以我为此创建了一个POJO,转到jsonschema2pojo并提供了我的JSON,它生成了我需要的所有文件。使用以下JSON,它为ParentCategory
字段创建了三个类,如ParentCategory_
,ParentCategory__
和parentCategory
。现在因为我不知道我有多少parentCategory
级别,所以我不确定为它们生成POJO的最佳方法是什么,并为最后id
提取parentCategory
字段。有没有办法用杰克逊做到这一点?
我必须阅读POJO中的所有这些数据,因为我也在阅读所有其他字段。
{
"paginationResponse": {
"pageNumber": 1,
"entriesPerPage": 200,
"totalPages": 3
},
"listings": [
{
"categories": [
{
"id": "79720",
"name": "Sunglasses",
"localizedName": "Sunglasses",
"level": 4,
"leafCategory": true,
"parentCategory": {
"id": "394",
"name": "Sunglasses & Fashion Eyewear",
"localizedName": "Sunglasses & Fashion Eyewear",
"level": 3,
"leafCategory": false,
"parentCategory": {
"id": "2340",
"name": "Men's Accessories",
"localizedName": "Men's Accessories",
"level": 2,
"leafCategory": false,
"parentCategory": {
"id": "10987",
"name": "Clothing, Shoes & Accessories",
"localizedName": "Clothing, Shoes & Accessories",
"level": 1,
"leafCategory": false
}
}
}
}
],
"processlisting": {
....
},
"processlistingmetainfo": {
...
},
"processlistingproperties": [
{
"propertyName": "item_url",
"propertyValues": [
{
"stringValue": "url"
}
]
},
{
"propertyName": "listing_site_id",
"propertyValues": [
{
"stringValue": "0"
}
]
}
]
}
],
"total": 100
}
注意:我无法控制此JSON结构,因为它不归我们所有,因此根本无法更改JSON结构。
以下是基于上述JSON生成的ParentCategory
的三个类,但一般情况下我可以有多个ParentCategory
级别,我事先并不知道。
public class ParentCategory {
@JsonProperty("id")
private String id;
@JsonProperty("name")
private String name;
@JsonProperty("localizedName")
private String localizedName;
@JsonProperty("level")
private long level;
@JsonProperty("leafCategory")
private boolean leafCategory;
@JsonProperty("parentCategory")
private ParentCategory_ parentCategory;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
....
}
public class ParentCategory_ {
@JsonProperty("id")
private String id;
@JsonProperty("name")
private String name;
@JsonProperty("localizedName")
private String localizedName;
@JsonProperty("level")
private long level;
@JsonProperty("leafCategory")
private boolean leafCategory;
@JsonProperty("parentCategory")
private ParentCategory__ parentCategory;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
...
}
public class ParentCategory__ {
@JsonProperty("id")
private String id;
@JsonProperty("name")
private String name;
@JsonProperty("localizedName")
private String localizedName;
@JsonProperty("level")
private long level;
@JsonProperty("leafCategory")
private boolean leafCategory;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
...
}
答案 0 :(得分:1)
一般而言 - 检索特定JSON属性的最佳工具是Json-Path,它提供了丰富的查询语言来搜索JSON树。
关于这个问题,需要检索两个不相关的属性,因此需要对JSON树进行两次扫描。问题没有说明如何读取输入,所以也许可以将整个输入流读入一个字符串。
下面是包含检索这两个属性所需查询的代码。无论parentCategory
级别的数量如何,这都将有效。诀窍是最后一个对象是唯一没有子parentCategory
的对象。
我在解释查询文本的代码中添加了注释
String categoryIdJsonPath =
"$" + // start from tree root
".listings[0]" + // get listings array's first (only) object
".categories[0]" + // get categories array's first (only) object
".id"; // get id property
String lastParentIdJsonPath =
"$" + // start from tree root
".listings[0]" + // get listings array's first (only) object
".categories[0]" + // get categories array's first (only) object
"..parentCategory" + // do deep scan for all nested parentCategory objects
"[?(!(@.parentCategory))]" + // filter by the object that does NOT have parentCategory property
".id"; // get id property
try {
// read the whole input so it can be scanned twice
String jsonInput = new String(Files.readAllBytes(Paths.get("C://temp/test.json")), Charset.forName("UTF-8"));
String categoryId = JsonPath.read(jsonInput, categoryIdJsonPath);
System.out.println(categoryId);
// return type is always List when deep scan is requested
List<String> lastParent = JsonPath.read(jsonInput, lastParentIdJsonPath);
System.out.println(lastParent.get(0));
} catch (Exception e) {
e.printStackTrace();
}