Я пытаюсь написать общий код для вложенного JsonObject для преобразования преобразования.
У меня есть образец JSONObject как
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized \n Markup Language",
"GlossDef": {
"para": "A DocBook.",
"GlossSeeAlso": [
"GML",
"XML"
]
},
"GlossSee": "markup"
}
}
}
}
}
Я хочу преобразовать его в карту с ключевым значением как
glossary.title = "example glossary",
glossary.GlossDiv.title = "S",
glossary.GlossDiv.GlossList.GlossEntry.ID = "SGML",
glossary.GlossDiv.GlossList.GlossEntry.SortAs = "SGML",
glossary.GlossDiv.GlossList.GlossEntry.GlossTerm = "Standard Generalized
Markup Language",
glosary.GlossDiv.GlossList.GlossEntry.GlossDef.para = "A DocBook.",
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso_0 = "GML",
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso_1 = "XML",
glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSee = "markup"




Jackson JSON - довольно классная библиотека, которая делает это за вас. Ниже я написал быстрый пример, но вы сможете применить его к своему JSONObject.
Допустим, у вас есть A.class со свойством B.class, у которого, в свою очередь, есть вложенное свойство C.class.
@JsonPropertyOrder({ "b" })
class A {
@JsonProperty("b")
public B b;
@JsonProperty("b")
public B getB() {
return b;
}
@JsonProperty("b")
public void setB(B b) {
this.b = b;
}
}
@JsonPropertyOrder({ "c" })
class B {
@JsonProperty("c")
public C c;
@JsonProperty("c")
public C getC() {
return c;
}
@JsonProperty("c")
public void setC(C c) {
this.c = c;
}
}
@JsonPropertyOrder({ "d" })
class C {
@JsonProperty("d")
public String d;
@JsonProperty("d")
public String getD() {
return d;
}
@JsonProperty("d")
public void setD(String d) {
this.d = d;
}
}
Вы можете преобразовать вложенный JSONObject {"b":{"c":{"d":"test"}}} в A.class следующим образом:
C c = new C();
c.setD("test");
B b = new B();
b.setC(c);
JSONObject obj = new JSONObject();
obj.put("b", b);
String jsonAsString = new Gson().toJson(obj);
A a = mapper.readValue(jsonAsString, A.class);
Точно так же вы должны иметь возможность преобразовать свой JSONObject в любой тип, который хотите. Надеюсь это поможет
Спасибо Bhargava за комментарии, но это не работает для вложенного JSON. И мне нужна правильная трассировка узлов. Так что этот подход не сработал
Неправильно прочитал исходный вопрос. Прости за это. Я обновил свой ответ. Сообщите мне, если это поможет.
Спасибо oleg.cherednik за вашу помощь. Не могли бы вы поделиться использованными входными данными и полученными выходными данными, потому что я пробовал, но безуспешно.
Это метод чтения Map из строки json с использованием Jackson:
public final class JsonUtils {
public static <T> Map<String, T> readMap(String json) throws Exception {
if (json == null)
return null;
ObjectReader reader = new ObjectMapper().readerFor(Map.class);
MappingIterator<Map<String, T>> it = reader.readValues(json);
if (it.hasNextValue()) {
Map<String, T> res = it.next();
return res.isEmpty() ? Collections.emptyMap() : res;
}
return Collections.emptyMap();
}
}
Вот как читать Map из json, используя данный служебный метод:
Map<String, String> map = flatMap(new LinkedHashMap<>(), "", JsonUtils.readMap(json));
И, наконец, вот как преобразовать Map в требуемый Map (вероятно, это можно было бы сделать в движке Джексона с предоставленными пользовательскими десериализаторами или около того, но я точно не знаю, как, и поэтому мне проще реализовать его вручную) :
public static Map<String, String> flatMap(Map<String, String> res, String prefix, Map<String, Object> map) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = prefix + entry.getKey();
Object value = entry.getValue();
if (value instanceof Map)
flatMap(res, key + '.', (Map<String, Object>)value);
else
res.put(key, String.valueOf(value));
}
return res;
}
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JsonToMapConvertor {
private static HashMap<String, Object> mapReturn = new HashMap<String, Object>();
public static JsonParser parser = new JsonParser();
public static void main(String[] args) throws Exception{
String json = "add your Json";
HashMap<String, Object> map = createHashMapFromJsonString(json,"");
for (Map.Entry<String, Object> entry : map.entrySet()) {
if (!entry.getValue().toString().contains("{"))
System.out.println(entry.getKey()+" : "+entry.getValue());
}
}
public static HashMap<String, Object> createHashMapFromJsonString(String json,String prefix) {
JsonObject object = (JsonObject) parser.parse(json);
Set<Map.Entry<String, JsonElement>> set = object.entrySet();
Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator();
while (iterator.hasNext()) {
Map.Entry<String, JsonElement> entry = iterator.next();
String key = entry.getKey();
if (prefix.length()!=0){
key = prefix + "."+key;
}
JsonElement value = entry.getValue();
if (null != value) {
if (!value.isJsonPrimitive()) {
if (value.isJsonObject()) {
mapReturn.put(key,value);
mapReturn.put(key, createHashMapFromJsonString(value.toString(),key));
} else if (value.isJsonArray() && value.toString().contains(":")) {
List<HashMap<String, Object>> list = new ArrayList<>();
JsonArray array = value.getAsJsonArray();
if (null != array) {
for (JsonElement element : array) {
list.add(createHashMapFromJsonString(value.toString(),key));
}
mapReturn.put(key, list);
}
} else if (value.isJsonArray() && !value.toString().contains(":")) {
mapReturn.put(key, value.getAsJsonArray());
}
} else {
mapReturn.put(key, value.getAsString());
}
}
}
return mapReturn;
}
}
Это работает, как и ожидалось, спасибо Бхаргава Нандибхатла, dkb и oleg.cherednik
Пожалуйста, отметьте ответ одного из других как принятый, а не отправляйте новый ответ.
Я не думаю, что это тот ответ, о котором просит участник. Если возможно, не могли бы вы опубликовать свой результат в ответе с теми же данными, что и в вопросе?