13

I have a String object containing some arbitrary json. I want to wrap it inside another json object, like this:

{
   version: 1,
   content: >>arbitrary_json_string_object<<
}

How can I reliably add my json string as an attribute to it without having to build it manually (ie avoiding tedious string concatenation)?

class Wrapper {
   int version = 1;
}

gson.toJson(new Wrapper())
// Then what?

Note that the added json should not be escaped, but a be part of the wrapper as a valid json entity, like this:

{
   version: 1,
   content: ["the content", {name:"from the String"}, "object"]
}

given

String arbitraryJson = "[\"the content\", {name:\"from the String\"}, \"object\"]";
Martin Wickman
  • 19,113
  • 11
  • 75
  • 101

5 Answers5

17

For those venturing on this topic, consider this.

A a = getYourAInstanceHere();
Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(a);
jsonElement.getAsJsonObject().addProperty("url_to_user", url);
return gson.toJson(jsonElement);
Community
  • 1
  • 1
T.K.
  • 2,119
  • 5
  • 21
  • 26
  • This should be accepted answer! Also, if you wish to add a custom object make another JsonElement like `JsonElement jsonElement2 = gson.toJsonTree(b);` and add to the existing one, using: `jsonElement.getAsJsonObject().add("other", jsonElement2);` – Sava Dimitrijević Apr 19 '19 at 10:48
8

Simple, convert your bean to a JsonObject and add a property.

Gson gson = new Gson();
JsonObject object = (JsonObject) gson.toJsonTree(new Wrapper());
object.addProperty("content", "arbitrary_json_string");
System.out.println(object);

prints

{"version":1,"content":"arbitrary_json_string"}
Sotirios Delimanolis
  • 263,859
  • 56
  • 671
  • 702
6

This is my solution:

  Gson gson = new Gson();
  Object object = gson.fromJson(arbitraryJson, Object.class);

  Wrapper w = new Wrapper();
  w.content = object;

  System.out.println(gson.toJson(w));

where I changed your Wrapper class in:

// setter and getters omitted
public class Wrapper {
  public int version = 1;
  public Object content;
}

You can also write a custom serializer for your Wrapper if you want to hide the details of the deserialization/serialization.

giampaolo
  • 6,788
  • 5
  • 43
  • 73
2

You will need to deserialize it first, then add it to your structure and re-serialize the whole thing. Otherwise, the wrapper will just contain the wrapped JSON in a fully escaped string.

This is assuming you have the following in a string:

{"foo": "bar"}

and want it wrapped in your Wrapper object, resulting in a JSON that looks like this:

{
    "version": 1,
    "content": {"foo": "bar"}
}

If you did not deserialize first, it would result in the following:

{
    "version": 1,
    "content": "{\"foo\": \"bar\"}"
}
jwueller
  • 29,756
  • 4
  • 63
  • 69
1

If you don't care about the whole JSON structure, you don't need to use a wrapper. You can deserialize it to a generic json object, and also add new elements after that.

JsonParser parser = new JsonParser();
JsonObject obj = parser.parse(jsonStr).getAsJsonObject();
obj.get("version"); // Version field
everton
  • 7,223
  • 2
  • 27
  • 41