linuxeasy
linuxeasy

Reputation: 6509

Modify json with GSON without using a POJO

I want to modify a json content without converting it into a POJO. I am using GSON Library.

Following are the use case:

String jsonString = "[{\"key1\":\"Hello\",\"key2\":\"World\"},{\"key1\":\"Nice\",\"key2\":\"Town\"}]";

JsonElement jsonElement = gson.fromJson(jsonString, JsonElement.class);     

Is there any way where I can set value of key1 to some value (let say "Test") in each array, without converting things into POJO

Upvotes: 18

Views: 35293

Answers (6)

Jonathan Mendoza
Jonathan Mendoza

Reputation: 480

Modify json with GSON JsonArray Java 8

Example of how to use GSON to modify a value within a JSON

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public class ModifyJson {
    public static void main(String[] args) {
        String data = "[{\"ct_pk\":24,\"ct_name\":\"SISTEMA DE PRUEBAS\"},"
                + "{\"ct_pk\":1,\"ct_name\":\"CAPITAL FEDERAL\"}," +
                "{\"ct_pk\":5,\"ct_name\":\"SISTEMA DE PRUEBAS DOS\"}]";

        System.out.println("before................." + data);

        JsonArray jsonArray = new Gson().fromJson(data, JsonElement.class).getAsJsonArray();
        JsonArray jsonArray2 = new JsonArray();
        for (JsonElement pa : jsonArray) {
            JsonObject jsonObject2 = pa.getAsJsonObject();
            String ct_name = jsonObject2.get("ct_name").getAsString();
            if (ct_name.equals("SISTEMA DE PRUEBAS")) {
                jsonObject2.addProperty("ct_name", "TODOS");
            }
            jsonArray2.add(jsonObject2);
        }
        System.out.println("after.................." +jsonArray2);
    }
}

Upvotes: 0

Bruce Edge
Bruce Edge

Reputation: 2189

Here's the shortest I came up with.

JsonElement je = new Gson().fromJson(jsonString, JsonElement.class);
JsonObject jo = je.getAsJsonObject();
jo.add("key", value);

Once you have the JsonObject, gson has many methods to manipulate it.

Upvotes: 18

SylvainL
SylvainL

Reputation: 3938

The jsonString is a plain, ordinary Java String; so you can modify it whatever you like using the standards String functions of Java and replace the substring key1 with Test1:

jsonString = "[{\"key1\":\"Test\",\"key2\":\"World\"},{\"key1\":\"Nice\",\"key2\":\"Town\"}]";

Of course, String in Java are immutable so converting it first to a StringBuilder will possibly give you a better performance in term of memory usage.

Upvotes: 0

Jeff Bowman
Jeff Bowman

Reputation: 95784

You can always get a different type than JsonElement, or use JsonElement.getAsJsonObject to cast to an Object (if possible).

String jsonString = "[{\"key1\":\"Hello\",\"key2\":\"World\"}, ...]";

JsonArray jsonArray = gson.fromJson(jsonString, JsonElement.class).getAsJsonArray();
JsonObject firstObject = jsonArray.get(i).getAsJsonObject();
firstObject.addProperty("key1", "Test");

I was wrong earlier; there seems to be no JsonArray adapter; you'll have to get a JsonElement and use the casting tool.

Upvotes: 3

fdreger
fdreger

Reputation: 12505

GSON has two separate APIs (that can be combined): one is used for serialization and deserialization, and the other for streaming. If you want to process streams of JSON without memory overhead or using dynamic structures (rather than static POJOs) you can do something like:

  • create a JsonWriter (in my example I use StringWriter);
  • create a JsonReader;
  • make a loop that consumes events from the reader and feeds them to the writer, possibly making changes, additions, omissions etc.

The loop will consist of a single switch statement that must have a case all the possible events (10 of them). Even the simplest example must have all of them, so the code below looks rather verbose. But it is very easy to extend and further extensions will not make it much longer.

An example that appends "test": 1 pair to each object looks something like:

public class Whatever {

static void streamandmodify(JsonReader reader, JsonWriter writer) throws IOException {
    while (true) {
        JsonToken token = reader.peek();
        switch (token) {
        // most cases are just consume the event
        // and pass an identical one to the writer
        case BEGIN_ARRAY:
            reader.beginArray();
            writer.beginArray();
            break;
        case END_ARRAY:
            reader.endArray();
            writer.endArray();
            break;
        case BEGIN_OBJECT:
            reader.beginObject();
            writer.beginObject();

            // this is where the change happens:
            writer.name("test");
            writer.value(1);
            break;
        case END_OBJECT:
            reader.endObject();
            writer.endObject();
            break;
        case NAME:
            String name = reader.nextName();
            writer.name(name);
            break;
        case STRING:
            String s = reader.nextString();
            writer.value(s);
            break;
        case NUMBER:
            String n = reader.nextString();
            writer.value(new BigDecimal(n));
            break;
        case BOOLEAN:
            boolean b = reader.nextBoolean();
            writer.value(b);
            break;
        case NULL:
            reader.nextNull();
            writer.nullValue();
            break;
        case END_DOCUMENT:
            return;
        }
    }
}


public static void main(String[] args) throws IOException {
    // just for test:
    JsonReader jr = new JsonReader(new StringReader("{\"a\":1, \"b\":{\"c\":[1,2,3,{},{}]}}"));
    StringWriter sw = new StringWriter();
    JsonWriter jw = new JsonWriter(sw);
    streamandmodify(jr, jw);
    System.out.println(sw.getBuffer().toString());
}
}

Upvotes: 0

Programmer Bruce
Programmer Bruce

Reputation: 67023

One approach would be to just convert the JSON to a java.util.Map, modify the Map, and go from there (which may mean serializing the Map back to JSON).

This approach meets my preference to work with the right API for the right job, minimizing the use of tools like Gson to just handle serialization/deserialization (which is what I understand it was designed for). That is, to not use the Gson API as a replacement data structure.

Upvotes: 2

Related Questions