Привет всем, я пытаюсь понять, как обновить часть моего json. До сих пор я не нашел нигде, где показано, как это сделать.
Например, вот что мне нужно обновить:
{
"lastUpdated": "",
"firetvs": [
{
"name": "lr",
"ip": "",
"mac": "",
"token": ""
},
{
"name": "mbr",
"ip": "",
"mac": "",
"token": ""
},...ETC....
Поэтому мне нужно обновить данные в разделе
"name": "mbr"
"mac": ""
часть, в которой мне нужно будет обновить Mac-адрес примерно так:
"name": "mbr"
"mac": "C1:41:Q4:E8:S1:98:V1"
Я нашел код, который позволяет мне обновлять стандартное значение, такое как мой LastUpdated, но не для чего-то, что является частью массива:
String jsonObject = "{" +
"\"lastUpdated\": \"\"," +
"\"firetvs\": [" +
"{" +
"\"name\": \"lr\"," +
"\"ip\": \"\"," +
"\"mac\": \"\"," +
"\"token\": \"\"" +
"}," +
"{" +
"\"name\": \"mbr\"," +
"\"ip\": \"\"," +
"\"mac\": \"\"," +
"\"token\": \"\"" +
"}" +
"]" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode objectNode = null;
try {
objectNode = objectMapper.readValue(jsonObject, ObjectNode.class);
objectNode.put("lastUpdated", "02-08-2024");
Log.d("test", objectNode.toPrettyString());
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
Я нашел это:
objectNode.with("firetvs").put("mac", "C1:41:Q4:E8:S1:98:V1");
Но это не сработает, поскольку он просто найдет первый экземпляр «mac» и обновит это значение вместо обновления второго его экземпляра. И я также получаю сообщение об ошибке:
Свойство firetvs имеет значение, не относящееся к типу ObjectNode (но com.fasterxml.jackson.databind.node.ArrayNode).
Итак, как бы мне это сделать?
Вам нужно поставить один и тот же mac-адрес всем элементам массива firetvs или только определенным?
@dani-vta это будет что-то конкретное. У меня есть больше массива, но я сократил его до 2, чтобы он не занимал так много места в моем вопросе.




Вы можете попробовать библиотеку JSON Josson.
https://github.com/octomix/josson
Josson josson = Josson.fromJsonString(
"{" +
"\"lastUpdated\": \"\"," +
"\"firetvs\": [" +
"{" +
"\"name\": \"lr\"," +
"\"ip\": \"\"," +
"\"mac\": \"\"," +
"\"token\": \"\"" +
"}," +
"{" +
"\"name\": \"mbr\"," +
"\"ip\": \"\"," +
"\"mac\": \"\"," +
"\"token\": \"\"" +
"}" +
"]" +
"}");
Map<String, JsonNode> params = Map.of(
"$date", TextNode.valueOf("02-08-2024"),
"$key", TextNode.valueOf("mbr"),
"$val", TextNode.valueOf("C1:41:Q4:E8:S1:98:V1")
);
JsonNode node = josson.getNode("field(lastUpdated:$date, firetvs.field(mac:if ([name=$key],$val,mac)))", params);
System.out.println(node.toPrettyString());
Выход
{
"lastUpdated" : "02-08-2024",
"firetvs" : [ {
"name" : "lr",
"ip" : "",
"mac" : "",
"token" : ""
}, {
"name" : "mbr",
"ip" : "",
"mac" : "C1:41:Q4:E8:S1:98:V1",
"token" : ""
} ]
}
Спасибо за пример и ссылку, Рэймонд!
Если вам нужно обновить MAC-адрес элементов firetvs только при определенных условиях, например, если name равен mbr, я предлагаю альтернативное решение с потоками.
По сути, элементы firetvs передаются через Iterable, затем фильтруются, сохраняя только те, у которых mbr являются name, и, наконец, обновляются с использованием правильного MAC-адреса.
В следующем примере я добавил всего пару элементов внутри firetvs, чтобы не загромождать код. Однако здесь, в oneCompiler, я включил больше элементов, показывающих желаемый результат.
public class Main {
public static void main(String[] args) throws JsonProcessingException {
String json = "{\n" +
" \"lastUpdated\": \"\",\n" +
" \"firetvs\": [\n" +
" {\n" +
" \"name\": \"lr\",\n" +
" \"ip\": \"\",\n" +
" \"mac\": \"\",\n" +
" \"token\": \"\"\n" +
" },\n" +
" {\n" +
" \"name\": \"mbr\",\n" +
" \"ip\": \"\",\n" +
" \"mac\": \"\",\n" +
" \"token\": \"\"\n" +
" }\n" +
" ]\n" +
"}";
String mac = "C1:41:Q4:E8:S1:98:V1";
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode rootNode = objectMapper.readValue(json, ObjectNode.class);
ArrayNode firetvsNode = (ArrayNode) rootNode.get("firetvs");
//Creating an Iterable form the Iterator of the firetvs' nodes
Iterable<JsonNode> iterable = () -> firetvsNode.iterator();
StreamSupport.stream(iterable.spliterator(), false) //Streaming the firetvs' nodes
.filter(node -> node.get("name").asText().equals("mbr")) //Keeping only the elements with mbr as their name
.forEach(node -> ((ObjectNode) node).put("mac", mac)); //Updating the mac address of each element
String jsonMacReplaced = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
System.out.println(jsonMacReplaced);
}
}
Я думаю, это может сработать для вас: 1. используйте метод objectNode.get("firetvs") и приведите его к объекту ArrayNode. 2. Возьмите второй элемент объекта ArrayNode и приведите его обратно к ObjectNode. 3. Теперь вы можете использовать метод put("mac", "C1:41:Q4:E8:S1:98:V1") для объекта, созданного во втором пункте.