13

I am coding a feature in which I read and write back json. However I can read the json elements from a file but can't edit the same loaded object. Here is my code which I am working on.

InputStream inp = new FileInputStream(jsonFilePath);
JsonReader reader = Json.createReader(inp);

JsonArray employeesArr = reader.readArray();
for (int i = 0; i < 2; i++) {
    JsonObject jObj = employeesArr.getJsonObject(i);
    JsonObject teammanager = jObj.getJsonObject("manager");

    Employee manager = new Employee();
    manager.name = teammanager.getString("name");
    manager.emailAddress = teammanager.getString("email");
    System.out.println("uploading File " + listOfFiles[i].getName());
    File file  = insertFile(...);
    JsonObject tmpJsonValue = Json.createObjectBuilder()
        .add("fileId", file.getId())
        .add("alternativeLink", file.getAlternateLink())
        .build();

    jObj.put("alternativeLink", tmpJsonValue.get("alternativeLink"));  <-- fails here 
}

I get the following exception when I run it.

Exception in thread "main" java.lang.UnsupportedOperationException

at java.util.AbstractMap.put(AbstractMap.java:203)

at com.mongodb.okr.DriveQuickstart.uploadAllFiles(DriveQuickstart.java:196)

at com.mongodb.okr.App.main(App.java:28)

Community
  • 1
  • 1
wayfare
  • 1,802
  • 5
  • 20
  • 37

4 Answers4

16

The javadoc of JsonObject states

JsonObject class represents an immutable JSON object value (an unordered collection of zero or more name/value pairs). It also provides unmodifiable map view to the JSON object name/value mappings.

You can't modify these objects.

You'll need to create a copy. There doesn't seem to be a direct way to do that. It looks like you'll need to use Json.createObjectBuilder() and build it yourself (see the example in the javadoc linked).

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
4

As answered by Sotirios, you can use JsonObjectBuilders. To insert value into JsonObject, you can use method:

private JsonObject insertValue(JsonObject source, String key, String value) {
    JsonObjectBuilder builder = Json.createObjectBuilder();
    builder.add(key, value);
    source.entrySet().
            forEach(e -> builder.add(e.getKey(), e.getValue()));
    return builder.build();
}

To insert JsonObject into JsonObject, you can use method:

private JsonObject insertObject(JsonObject parent, JsonObject child, String childName) {
    JsonObjectBuilder child_builder = Json.createObjectBuilder();
    JsonObjectBuilder parent_builder = Json.createObjectBuilder();
    parent.entrySet().
            forEach(e -> parent_builder.add(e.getKey(), e.getValue()));
    child.entrySet().
            forEach(e -> child_builder.add(e.getKey(), e.getValue()));
    parent_builder.add(childName, child_builder);
    return parent_builder.build();
}

Please note, if you change the child JsonObject after inserting it into another "parent" JsonObject, it will have no effect on the "parent" JsonObject.

Lubos Prague
  • 101
  • 1
  • 3
  • 1
    In your first method , `builder.add` should be called after iterating the entry set, otherwise you could potentially overwrite a key that you've added to. – Kajzer May 04 '23 at 11:11
0

JsonObject is immutable so you cannot modify the object , you can use this example and try to inspire from it : creation of a new JsonObject who contains the same values and add some elements to it ..

Example :

        import java.io.ByteArrayInputStream;
        import java.io.InputStream;

        import javax.json.Json;
        import javax.json.JsonArray;
        import javax.json.JsonArrayBuilder;
        import javax.json.JsonObject;
        import javax.json.JsonObjectBuilder;
        import javax.json.JsonReader;
        import javax.json.JsonValue;


        public class Jsonizer {
        public static void main(String[] args) {

    try {
        String s = "{\"persons\": [ {\"name\":\"oussama\",\"age\":\"30\"}, {\"name\":\"amine\",\"age\":\"25\"} ]}";
        InputStream is = new ByteArrayInputStream(s.getBytes());
        JsonReader jr = Json.createReader(is);
        JsonObject jo = jr.readObject();
        System.out.println("Before :");
        System.out.println(jo);
        JsonArray ja = jo.getJsonArray("persons");

        InputStream targetStream = new ByteArrayInputStream("{\"name\":\"sami\",\"age\":\"50\"}".getBytes());
        jr = Json.createReader(targetStream);
        JsonObject newJo = jr.readObject();
        JsonArrayBuilder jsonArraybuilder = Json.createArrayBuilder();
        jsonArraybuilder.add(newJo);
        
        for (JsonValue jValue : ja) {
            jsonArraybuilder.add(jValue);
        }
        
        ja = jsonArraybuilder.build();
        JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
        jsonObjectBuilder.add("persons", ja);
        JsonObject jsonAfterAdd = jsonObjectBuilder.build();
        System.out.println("After");
        System.out.println(jsonAfterAdd.toString());

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

  }
 }

Output :

       Before :
       {"persons":[{"name":"oussama","age":"30"},{"name":"amine","age":"25"}]}
       After
       {"persons":[{"name":"sami","age":"50"},{"name":"oussama","age":"30"},{"name":"amine","age":"25"}]}
Oussama ZAGHDOUD
  • 1,767
  • 5
  • 15
0

Try using the simple JSONObject, not javax.

import org.json.JSONObject;

You can download the jar or include it in your maven or gradle like so:

dependencies {
  compile group: 'com.googlecode.json-simple', name: 'json-simple', version: '1.1.1'
}

also see: creating json string using JSONObject and JSONArray

john k
  • 6,268
  • 4
  • 55
  • 59