javajsonjacksonnodesobjectmapper

Java Jackson update json 2nd value instance in array


Hey all I am trying to figure out how to go about updating a part of my json. So far I have not found anywhere that shows me how to do this.

For an example, this is what I am needing to update:

{
    "lastUpdated": "",
    "firetvs": [
        {
            "name": "lr",
            "ip": "",
            "mac": "",
            "token": ""
        },
        {
            "name": "mbr",
            "ip": "",
            "mac": "",
            "token": ""
        },...ETC....

So I am needing to update the data under the

"name": "mbr"
 "mac": ""

part which I would need to update the mac address to something like:

"name": "mbr"
 "mac": "C1:41:Q4:E8:S1:98:V1"

I have found code that allows me to update a standard value like my lastUpdated but not for something that's part of an array:

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);
}

I did find this:

objectNode.with("firetvs").put("mac", "C1:41:Q4:E8:S1:98:V1");

But that wont work since its just going to find the first instance of "mac" and update that value instead of updating the 2nd instance of it. And I also get an error of:

Property 'firetvs' has value that is not of type ObjectNode (but com.fasterxml.jackson.databind.node.ArrayNode)

So, how would I accomplish this?


Solution

  • You may try JSON library 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());
    

    Output

    {
      "lastUpdated" : "02-08-2024",
      "firetvs" : [ {
        "name" : "lr",
        "ip" : "",
        "mac" : "",
        "token" : ""
      }, {
        "name" : "mbr",
        "ip" : "",
        "mac" : "C1:41:Q4:E8:S1:98:V1",
        "token" : ""
      } ]
    }