У меня есть ObjectNode
как входной параметр, и я не знаю точной структуры этого узла. Я имею в виду, что он может иметь любое количество слоев внутри, от очень простого массива NameValuePair<String,String>
до сложной структуры, такой как HashMap<String,Object>
. Как я могу разобрать его на простую плоскую структуру, например массив NameValuePair<String,String>
? Я сделал это раньше для ObjectNodes
с известной структурой, но теперь я понятия не имею.
Я ценю любую помощь и любые идеи.
Добавление сведений: например, если я знаю, что внутри ObjectNode я всегда найду только HashMap<String,String>
, и все, что я могу сделать:
ObjectNode parametersNode = (ObjectNode) request.get("parameters");
Iterator fieldNames = parametersNode.getFieldNames();
HashMap<String,String> oldParams = new HashMap<String,String>();
while (fieldNames.hasNext()) {
String name = (String) fieldNames.next();
oldParams.put(name, parametersNode.get(name).asText());
}
Но что, если структура этого ObjectNode является черным ящиком? Я не знаю, есть карта или массив, или куча карт внутри Карты. Это может быть из разных источников, и я не знаю, какую структуру я получу в любой момент. может быть:
{
"name":"value",
"name1":"value1"
}
или
{
"name":"value",
"arg1": [
"name1":"value1",
"name1":"value1"
]
}
или
{
"name":"value",
"arg1": [
{"name1":"value1"},
{"name1":"value1"}
]
}
или более сложной структуры. И у меня нет информации заранее, что я получаю. Как преобразовать такой черный ящик ObjectNode в плоский массив пар имя-значение? Есть ли универсальный алгоритм?
В конце я должен получить простую структуру, как это, несмотря на сложность исходной структуры:
{
"name":"value",
"name1":"value1",
"name2":"value2"
}
Поскольку у меня нет ответов, я сделал это сам. Для тех, кто столкнутся с той же проблемой, я размещаю ее здесь. Это без какой-либо рекурсии, и я использовал HashMap, где я не должен, но это как доказательство концепции и предназначено для рефакторинга. Обратите внимание, что он был протестирован как веб-сервис на Switchyard через Postman, поэтому никакого основного метода.
public ArrayList<HashMap<String, String>> convertToFlatFormat(
JsonNode request) {
Stack<Pair> stack = new Stack<Pair>();
ArrayList<HashMap<String, String>> parametersList = new ArrayList<HashMap<String, String>>();
stack.push(new Pair("", request));
HashMap<String, Integer> counts = new HashMap<String, Integer>();
while (!stack.isEmpty()) {
Pair higherNodePair = stack.pop();
String nodeName = higherNodePair.name;
JsonNode higherNode = (JsonNode) higherNodePair.object;
String newNamePrefix = "";
if (higherNode.isArray()) {
ArrayNode higherArrayNode = (ArrayNode) higherNode;
for (int i = 0; i < higherNode.size(); i++) {
JsonNode node = higherArrayNode.get(i);
String key = new Integer(i).toString();
if (node.isObject()) {
if (nodeName.equals("")) {
stack.push(new Pair(newNamePrefix, node));
} else {
stack.push(new Pair(nodeName + "_" + newNamePrefix
, node));
}
} else if (node.isArray()) {
if (nodeName.equals("")) {
stack.push(new Pair(newNamePrefix, node));
} else {
stack.push(new Pair(nodeName + "_" + newNamePrefix
, node));
}
} else if (node.isValueNode()) {
ValueNode valueNode = (ValueNode) node;
String value = valueNode.getTextValue();
HashMap<String, String> pair = null;
if (nodeName.equals("")) {
pair = new HashMap<String, String>();
pair.put(newNamePrefix + key, value);
} else {
pair = new HashMap<String, String>();
pair.put(nodeName + "_" + newNamePrefix + key,
value);
}
parametersList.add(pair);
}
}
} else {
Iterator<String> iterate = higherNode.getFieldNames();
while (iterate.hasNext()) {
String key = iterate.next();
JsonNode node = higherNode.get(key);
if (node.isObject()) {
if (nodeName.equals("")) {
stack.push(new Pair(newNamePrefix + key, node));
} else {
stack.push(new Pair(nodeName + "_" + newNamePrefix
+ key, node));
}
} else if (node.isArray()) {
if (nodeName.equals("")) {
stack.push(new Pair(newNamePrefix + key, node));
} else {
stack.push(new Pair(nodeName + "_" + newNamePrefix
+ key, node));
}
} else if (node.isValueNode()) {
ValueNode valueNode = (ValueNode) node;
String value = valueNode.getTextValue();
HashMap<String, String> pair = null;
if (nodeName.equals("")) {
pair = new HashMap<String, String>();
pair.put(newNamePrefix + key, value);
} else {
pair = new HashMap<String, String>();
pair.put(nodeName + "_" + newNamePrefix + key,
value);
}
parametersList.add(pair);
}
}
}
}
return parametersList;
}
private class Pair {
public String name;
public Object object;
public Pair(String name, Object object) {
this.name = name;
this.object = object;
}
}
Вход:
{
"name1":"value1",
"name2":"value2",
"name3":[
{
"ComponentId":"qwer",
"InstanceId":"amba"
},
{
"ComponentId":"qwer",
"InstanceId":"coramba"
},
{
"ComponentId":"dsa",
"InstanceId":"badar"
},
{
"ComponentId":"dsa",
"InstanceId":"fdarr"
},
{
"ComponentId":"dsa",
"InstanceId":"sdddd"
}
]
}
Выход:
[
{
"name1": "value1"
},
{
"name2": "value2"
},
{
"name3__dsa_1_ComponentId": "dsa"
},
{
"name3__dsa_1_InstanceId": "sdddd"
},
{
"name3__dsa_2_ComponentId": "dsa"
},
{
"name3__dsa_2_InstanceId": "fdarr"
},
{
"name3__dsa_3_ComponentId": "dsa"
},
{
"name3__dsa_3_InstanceId": "badar"
},
{
"name3__qwer_1_ComponentId": "qwer"
},
{
"name3__qwer_1_InstanceId": "coramba"
},
{
"name3__qwer_2_ComponentId": "qwer"
},
{
"name3__qwer_2_InstanceId": "amba"
}
]