#java #json
#java #json
Вопрос:
Я борюсь с конкретной проблемой, о которой я не могу думать правильно. Проблема заключается в следующем
У меня есть карта со значением ключа, как показано ниже, я просто использовал здесь строки
String key = "activate.message.success"
String value = "success"
String key1 = "activate.title"
String value1 = "Good Title"
String key2 = "activate.message.error"
String value2 = "error"
String key3 = "activate.message.short.poll"
String value3 = "This is short poll"
Мне нужно создать json следующим образом
{
"activate":{
"message":{
"success":"success",
"error":"error",
"short":{
"poll":"This is short poll"
}
},
"title":"Good Title"
}
}
Я не мог придумать правильного решения для этого варианта использования и боролся в течение 3 часов. Я думал об использовании рекурсии, но я не знаю, как именно я мог бы это сделать. Пожалуйста, помогите с этим. Я использую java для этого, я должен использовать generic JSONObject для решения, поскольку нет сопоставлений POJO. До сих пор я просто разделял строки с помощью separtor и сохранял в другой карте, например, следующим образом
public Map<String, Object> getJsonObjectFromKeyValueMap(Map<String, String> stringValueMap,
Map<String, Object> stringObjectMap) {
for (Entry entry : stringValueMap.entrySet()) {
String[] keyValueArrayString = entry.getKey().toString().split("\.");
int sizeOfMap = keyValueArrayString.length;
int i = 0;
String concatString = "";
for (String processKey : keyValueArrayString) {
if (i < sizeOfMap - 1) {
concatString = processKey ".";
stringObjectMap.put(concatString, (Object) new JSONObject());
} else {
concatString = processKey;
stringObjectMap.put(concatString, entry.getValue());
concatString = "";
}
i ;
}
}
return stringObjectMap;
}
Комментарии:
1. пожалуйста, покажите нам, что вы пробовали до сих пор
2. Добавлено это, я попытался разделить строку с помощью точки и сохранить ее в другой карте, например, следующим образом
3. Разделите ключ на a
.
, затем для каждого «значения» проверьте, существует ли уже узел (JSONObject). Если нет, создавайте его, пока не дойдете до конца, где вы помещаете значение JSON. Это почти то, что вы делаете, при условии, что вы создаете новый JSONObject, несмотря ни на что.
Ответ №1:
Во-первых, давайте обновим ваши данные до правильной карты :
Map<String, String> data = new HashMap<>();
data.put("activate.message.success", "success");
data.put("activate.title", "Good Title");
data.put("activate.message.error", "error");
data.put("activate.message.short.poll", "This is short poll");
Затем ваша логика довольно близка, для каждого узла, кроме последнего, вы создаете новый JSONObject, для последнего вы вставляете значение.
Если вы попытаетесь создать JSONObject вместо карты напрямую, вы получите уже довольно хороший результат, ну, в некотором роде результат.
Далее будет выполняться итерация Map<String, String>
данных. Для каждой записи мы разделяем ключ для получения узлов.
Затем нам просто нужно переместить json
, если узел не существует, мы его создаем. Затем для последнего значения создайте значение.
public static JSONObject build(Map<String, String> data) {
JSONObject json = new JSONObject();
//Iterate the map entries
for (Entry<String, String> e : data.entrySet()) {
String[] keys = e.getKey().split("\.");
// start from the root
JSONObject current = json;
for (int i = 0; i < keys.length; i) {
String key = keys[i];
//Search for the current node
try {
//If it exist, do nothing
current = current.getJSONObject(key);
} //If it does not exist
catch (JSONException ex) {
//Is it the last node, create the value
if (i == keys.length - 1) {
current.put(key, e.getValue());
} //Not the last node, create a new JSONObject
else {
JSONObject tmp = new JSONObject();
current.put(key, tmp);
current = tmp; //Always replace current with the last node to go deeped each iteration
}
}
}
}
return json;
}
И пример :
public static void main(String[] args) {
Map<String, String> data = new HashMap<>();
data.put("activate.message.success", "success");
data.put("activate.title", "Good Title");
data.put("activate.message.error", "error");
data.put("activate.message.short.poll", "This is short poll");
JSONObject json = build(data);
System.out.println(json.toString(4));
}
Вывод:
{"activate": {
"message": {
"success": "success",
"short": {"poll": "This is short poll"},
"error": "error"
},
"title": "Good Title"
}}
Примечание: я использовал исключение для проверки наличия ключа, если карта огромная, это может оказать некоторое влияние, поэтому вы можете просто использовать :
if(current.isNull(key)){
if (i == keys.length - 1) {
current.put(key, e.getValue());
} else {
JSONObject tmp = new JSONObject();
current.put(key, tmp);
current = tmp;
}
} else {
current = current.getJSONObject(key);
}
Это было создано с использованием org.json / json
Комментарии:
1. Спасибо Алекшу за это замечательное усилие, я проверю и дам знать завтра