Reputation: 6509
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
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
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
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
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
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:
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
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