问题描述
我有一个以下的JSON,我需要从中生成一个 Map< String,String>
。在下面的JSON中,我只有三个级别的 parentCategory
,但一般来说它可以更多或有时可以更少。
I have a below JSON and from which I need to make a Map<String, String>
. In the below JSON, I have only three levels of parentCategory
but in general it can be more or sometimes it can be less.
- 我的地图的密钥是
79720
这是id
的类别
部分和值应为10987
这是id
的最后parentCategory
。
- Key of my map will be
79720
which isid
ofcategories
section and value should be10987
which isid
of lastparentCategory
.
现在我可以在其中嵌套 parentCategory
,这样我就会遇到问题这是一个POJO。我可以有一个级别 parentCategory
或者我可以在每个 parentCategory $中嵌套
parentCategory
c $ c>我总是需要获取最后一个 parentCategory
的id。
Now I can have nested parentCategory
inside them so I am having issues making a POJO for this. I can have one level parentCategory
or I can have nested parentCategory
inside each parentCategory
and I always need to get id for the last parentCategory
.
所以我创建了一个POJO通过访问并提供我的JSON,它生成了我需要的所有文件。使用以下JSON,它创建了三个类,如 ParentCategory
, ParentCategory _
和 ParentCategory __
表示 parentCategory
字段。现在因为我不知道有多少 parentCategory
级别,所以我不确定为它们生成POJO的最佳方法是什么并提取 id
最后 parentCategory
的字段。有什么方法可以使用Jackson吗?
So I am creating a POJO for this by going to jsonschema2pojo and provided my JSON where it generated me all the files that I need. With the below JSON, it has created three classes like this ParentCategory
, ParentCategory_
and ParentCategory__
for parentCategory
field. Now since I don't know how many parentCategory
levels I have so I am not sure what is the best way to generate a POJO for them and extract id
field for last parentCategory
. Is there any way to do this using Jackson?
我必须阅读POJO中的所有这些数据,因为我也在阅读所有其他字段。
I have to read all this data in POJO as I am also reading all other fields as well.
{
"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结构。
Note: I don't have control over this JSON structure as it's not owned by us so can't change JSON structure at all.
以下是基于上述JSON生成的 ParentCategory
的三个类,但一般情况下我可以有多个级别 ParentCategory
我事先不知道。
Below are the three classes for ParentCategory
which was generated basis on above JSON but in general I can have multiple levels of ParentCategory
and I don't know beforehand.
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树。
Generally speaking - The best tool for the task of retrieving particular JSON properties is Json-Path which provides a rich query language to search a JSON tree.
关于这个问题,需要检索两个不相关的属性,因此需要两次扫描需要JSON树。问题没有说明如何读取输入,所以也许可以将整个输入流读入一个字符串。
Regarding the question, it is requried to retrieve two unrelated properties, so two scans of the JSON tree are required. The question does not specify how the input is read, so perhaps it is possible to read the whole input stream into one String.
下面是需要查询的代码检索这两个属性。无论 parentCategory
级别的数量如何,这都将有效。诀窍是最后一个对象是唯一一个没有孩子的对象 parentCategory
。
Below is the code with the queries needed to retrieve both properties. This will work regardless of the number of parentCategory
levels. The trick is that the last object is the only one that does not have a child parentCategory
.
我添加了对解释查询文本的代码的注释
I have added comments to the code that explain the query text
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();
}
这篇关于使用jackson解析递归嵌套字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!