14

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,662
  • 12
  • 82
  • 106

5 Answers5

19

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,229
  • 5
  • 22
  • 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
  • 274,122
  • 60
  • 696
  • 724
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,906
  • 5
  • 45
  • 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
  • 30,582
  • 4
  • 66
  • 70
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,579
  • 2
  • 29
  • 42