我有一个下面的JSON,我需要从中制作一个Map<String, String>。在下面的JSON中,我只有3个级别,parentCategory但通常可以更高,有时也可以更低。
Map<String, String>
parentCategory
79720
id
categories
10987
现在我可以嵌套parentCategory在其中,因此在为此创建POJO时遇到问题。我可以有一个级别parentCategory,也可以嵌套parentCategory在每个级别中,parentCategory而我总是需要获取最后一个的ID parentCategory。
因此,我通过转到jsonschema2pojo来为此创建一个POJO,并提供了JSON,它在其中生成了我所需的所有文件。随着下面的JSON,它创造了三个班这样的ParentCategory,ParentCategory_并ParentCategory__为parentCategory现场。现在,由于我不知道parentCategory我有多少个级别,所以我不确定为它们生成POJO并id最后提取字段的最佳方法是什么parentCategory。有没有办法用杰克逊做到这一点?
ParentCategory
ParentCategory_
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结构。
以下是ParentCategory根据上面的JSON生成的三个类,但是通常我可以具有多个级别,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>(); ... }
一般而言-检索特定JSON属性的最佳工具是Json-Path,它提供了丰富的查询语言来搜索JSON树。
关于该问题,需要检索两个不相关的属性,因此需要对JSON树进行两次扫描。该问题未指定如何读取输入,因此也许可以将整个输入流读取为一个String。
下面是带有检索这两个属性所需的查询的代码。无论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(); }