使用 Jackson 解析数组 JSON 模式
Parse array JSON Schema with Jackson
我有一个 JSON 架构定义:
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "array",
"title": "The Root Schema",
"items": {
"$id": "#/items",
"type": "object",
"title": "The Items Schema",
"required": [
"test",
"isExpand",
"numberOfIssue",
"issue",
"listOfDetails"
],
"properties": {
"test": {
"$id": "#/items/properties/test",
"type": "string",
"title": "The Test Schema",
"default": "",
"examples": [
"value"
],
"pattern": "^(.*)$"
},
"isExpand": {
"$id": "#/items/properties/isExpand",
"type": "boolean",
"title": "The Isexpand Schema",
"default": false,
"examples": [
true
]
},
"numberOfIssue": {
"$id": "#/items/properties/numberOfIssue",
"type": "integer",
"title": "The Numberofissue Schema",
"default": 0,
"examples": [
1
]
},
"issue": {
"$id": "#/items/properties/issue",
"type": "object",
"title": "The Issue Schema",
"required": [
"mappingId"
],
"properties": {
"mappingId": {
"$id": "#/items/properties/issue/properties/mappingId",
"type": "string",
"title": "The Mappingid Schema",
"default": "",
"examples": [
"1561561"
],
"pattern": "^(.*)$"
}
}
},
"listOfDetails": {
"$id": "#/items/properties/listOfDetails",
"type": "array",
"title": "The listOfDetails Schema",
"items": {
"$id": "#/items/properties/listOfDetails/items",
"type": "object",
"title": "The Items Schema",
"required": [
"self",
"detailId"
],
"properties": {
"self": {
"$id": "#/items/properties/listOfDetails/items/properties/self",
"type": "string",
"title": "The Self Schema",
"default": "",
"examples": [
"self1"
],
"pattern": "^(.*)$"
},
"issueId": {
"$id": "#/items/properties/listOfDetails/items/properties/detailId",
"type": "string",
"title": "The detailId Schema",
"default": "",
"examples": [
"000188181"
],
"pattern": "^(.*)$"
}
}
}
}
}
}
}
它将始终是一个架构,首先包含 items,然后包含 properties。
在属性中可以找到更多数组或对象,所以我想递归地这样做。
我想要实现的是 Map<String, Object>
直接表示模式。我卡住的地方是当前 属性 是对象或数组的递归调用。
我想实现这个:
{
"test" : "",
"isExpand" : false,
"numberOfIssues" : 0,
"issue" : {
"mappingId" : ""
},
"listOfDetails" : [
{
"self" : "",
"detailId" : ""
}
]
}
这是我从文件中解析出 JsonSchema 并从中获取实际属性的方法
private static void parseJsonNode(String path) throws Exception {
ObjectMapper mapper = new ObjectMapper(new JsonFactory());
JsonNode rootNode = mapper.readTree(new File(METADATA_SCHEMA_PATH + path));
Map<String, Object> elementsMap = new HashMap<>();
fillHashMap(elementsMap, rootNode.get("items").get("properties"));
}
elementsMap
是全局定义的 Map<String, Object>
Map<String, Object> elementsMap = new HashMap<>();
private static Map<String, Object> fillHashMap(Map<String, Object> elementsMap, JsonNode rootNode) throws Exception {
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldsIterator.next();
if (field.getValue().get("type").toString().contains("array")) {
//TODO HOW TO HANDLE ARRAY THERE
} else if (field.getValue().get("type").toString().contains("object")) {
elementsMap.put(field.getKey(), fillHashMap(elementsMap, field.getValue().get("properties")));
} else {
elementsMap.put(field.getKey(), field.getValue().get("default"));
}
}
return elementsMap;
}
我卡在递归调用 fillHashMap() 上了。当我拆箱对象属性时,它会转到 else 分支,将 mappingId 直接放到地图上,这在拆箱后是合乎逻辑的..但我猜我正在做这一切错了..有人可以指出我应该改变什么以达到我想要的结果吗?谢谢!!
我自己想出来了。也许它会帮助某人。
private static void parseJsonNode(String path) throws Exception {
ObjectMapper mapper = new ObjectMapper(new JsonFactory());
JsonNode rootNode = mapper.readTree(new File(BASE_PATH + path));
Map<String, Object> elementsMap =
fillHashMap(rootNode.get("items").get("properties"));
System.out.println(elementsMap);
}
private static Map<String, Object> fillHashMap(JsonNode rootNode) {
Map<String, Object> elementsMap = new HashMap<>();
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldsIterator.next();
if (field.getValue().get("type").toString().contains("array")) {
List<Map<String, Object>> objectArray = new ArrayList<>();
JsonNode itemsNode = field.getValue().get("items").get("properties");
objectArray.add(fillHashMap(itemsNode));
elementsMap.put(field.getKey(), objectArray);
} else if (field.getValue().get("type").toString().contains("object")) {
elementsMap.put(field.getKey(),
fillHashMap(field.getValue().get("properties")));
} else {
elementsMap.put(field.getKey(), field.getValue().get("default"));
}
}
return elementsMap;
}
我有一个 JSON 架构定义:
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://example.com/root.json",
"type": "array",
"title": "The Root Schema",
"items": {
"$id": "#/items",
"type": "object",
"title": "The Items Schema",
"required": [
"test",
"isExpand",
"numberOfIssue",
"issue",
"listOfDetails"
],
"properties": {
"test": {
"$id": "#/items/properties/test",
"type": "string",
"title": "The Test Schema",
"default": "",
"examples": [
"value"
],
"pattern": "^(.*)$"
},
"isExpand": {
"$id": "#/items/properties/isExpand",
"type": "boolean",
"title": "The Isexpand Schema",
"default": false,
"examples": [
true
]
},
"numberOfIssue": {
"$id": "#/items/properties/numberOfIssue",
"type": "integer",
"title": "The Numberofissue Schema",
"default": 0,
"examples": [
1
]
},
"issue": {
"$id": "#/items/properties/issue",
"type": "object",
"title": "The Issue Schema",
"required": [
"mappingId"
],
"properties": {
"mappingId": {
"$id": "#/items/properties/issue/properties/mappingId",
"type": "string",
"title": "The Mappingid Schema",
"default": "",
"examples": [
"1561561"
],
"pattern": "^(.*)$"
}
}
},
"listOfDetails": {
"$id": "#/items/properties/listOfDetails",
"type": "array",
"title": "The listOfDetails Schema",
"items": {
"$id": "#/items/properties/listOfDetails/items",
"type": "object",
"title": "The Items Schema",
"required": [
"self",
"detailId"
],
"properties": {
"self": {
"$id": "#/items/properties/listOfDetails/items/properties/self",
"type": "string",
"title": "The Self Schema",
"default": "",
"examples": [
"self1"
],
"pattern": "^(.*)$"
},
"issueId": {
"$id": "#/items/properties/listOfDetails/items/properties/detailId",
"type": "string",
"title": "The detailId Schema",
"default": "",
"examples": [
"000188181"
],
"pattern": "^(.*)$"
}
}
}
}
}
}
}
它将始终是一个架构,首先包含 items,然后包含 properties。
在属性中可以找到更多数组或对象,所以我想递归地这样做。
我想要实现的是 Map<String, Object>
直接表示模式。我卡住的地方是当前 属性 是对象或数组的递归调用。
我想实现这个:
{
"test" : "",
"isExpand" : false,
"numberOfIssues" : 0,
"issue" : {
"mappingId" : ""
},
"listOfDetails" : [
{
"self" : "",
"detailId" : ""
}
]
}
这是我从文件中解析出 JsonSchema 并从中获取实际属性的方法
private static void parseJsonNode(String path) throws Exception {
ObjectMapper mapper = new ObjectMapper(new JsonFactory());
JsonNode rootNode = mapper.readTree(new File(METADATA_SCHEMA_PATH + path));
Map<String, Object> elementsMap = new HashMap<>();
fillHashMap(elementsMap, rootNode.get("items").get("properties"));
}
elementsMap
是全局定义的 Map<String, Object>
Map<String, Object> elementsMap = new HashMap<>();
private static Map<String, Object> fillHashMap(Map<String, Object> elementsMap, JsonNode rootNode) throws Exception {
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldsIterator.next();
if (field.getValue().get("type").toString().contains("array")) {
//TODO HOW TO HANDLE ARRAY THERE
} else if (field.getValue().get("type").toString().contains("object")) {
elementsMap.put(field.getKey(), fillHashMap(elementsMap, field.getValue().get("properties")));
} else {
elementsMap.put(field.getKey(), field.getValue().get("default"));
}
}
return elementsMap;
}
我卡在递归调用 fillHashMap() 上了。当我拆箱对象属性时,它会转到 else 分支,将 mappingId 直接放到地图上,这在拆箱后是合乎逻辑的..但我猜我正在做这一切错了..有人可以指出我应该改变什么以达到我想要的结果吗?谢谢!!
我自己想出来了。也许它会帮助某人。
private static void parseJsonNode(String path) throws Exception {
ObjectMapper mapper = new ObjectMapper(new JsonFactory());
JsonNode rootNode = mapper.readTree(new File(BASE_PATH + path));
Map<String, Object> elementsMap =
fillHashMap(rootNode.get("items").get("properties"));
System.out.println(elementsMap);
}
private static Map<String, Object> fillHashMap(JsonNode rootNode) {
Map<String, Object> elementsMap = new HashMap<>();
Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
while (fieldsIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldsIterator.next();
if (field.getValue().get("type").toString().contains("array")) {
List<Map<String, Object>> objectArray = new ArrayList<>();
JsonNode itemsNode = field.getValue().get("items").get("properties");
objectArray.add(fillHashMap(itemsNode));
elementsMap.put(field.getKey(), objectArray);
} else if (field.getValue().get("type").toString().contains("object")) {
elementsMap.put(field.getKey(),
fillHashMap(field.getValue().get("properties")));
} else {
elementsMap.put(field.getKey(), field.getValue().get("default"));
}
}
return elementsMap;
}