1

I have a map of JSON objects as follows:

Map<String,Object> map = HashMap<String,Object>();
map.put("first_name", "prod");
JSONObject jsonObj = new JSONObject("some complex json string here");
map.put("data", jsonObj);

Gson gson = new Gson();
String result = gson.toJson(map);

Now if the "some complex JSON string here" was:

{"sender":{"id":"test test"},"recipients":{"id":"test1 test1"} }

and execute above code gives me something like:

{
    "first_name": "prod",
    "data": {
        "map": {
            "sender": {
                "map": {
                    "id": "test test"
                    }
                }
            },
            "recipients": {
                "map": {
                    "id": "test1 test1"
                }
            }
        }
    }
}

I might have some syntax error up there, but basically I don't know why I am seeing objects wrapped around map's.

Update

according to comments, it is a bad idea to mix different json parsers. i can understand that. but my case requires calling an external api which takes a hash map of objects that are deserialized using gson eventually.

is there any other object bedsides JSONObject that i can add to the map and still have gson create json out of it without extra 'map' structure? i do understand that i can create java beans and achieve this. but i'm looking for a simpler way since my data structure can be complex.

Update2

going one step back, i am given a xml string. and i have converted them to json object. now i have to use an external api that takes a map which in turn gets converted to json string using gson in external service.

so i am given an xml data structure, but i need to pass a map to that function. the way i have described above produces extra 'map' structures when converted to json string using gson. i do not have control to change how the external service behaves (e.g. using gson to convert the map).

3
  • Mixing classes from two different JSON parsing libraries is a recipe for disaster. Commented Jan 21, 2014 at 2:44
  • You'd have to give us an example of the HashMap content and what you want to add to it. It's not clear exactly what you want. Commented Jan 21, 2014 at 15:35
  • i am trying to create a hashmap that can be converted to json string later using gson. but for my need, i need to create that map, and not the json string. i just need to know that this map "can" be converted to json string using gson with having extra 'map's Commented Jan 21, 2014 at 17:45

4 Answers 4

3

Mixing classes from two different JSON libraries will end in nothing but tears. And that's your issue; JSONObject is not part of Gson. In addition, trying to mix Java data structures with a library's parse tree representations is also a bad idea; conceptually an object in JSON is a map.

If you're going to use Gson, either use all Java objects and let Gson convert them, or use the classes from Gson:

JsonObject root = new JsonObject();
root.addProperty("first_name", "prod");

JsonElement element = new JsonParser().parse(complexJsonString);
root.addProperty("data", element);

String json = new Gson().toJson(root);
Sign up to request clarification or add additional context in comments.

4 Comments

while this is a good solution, i need a hashmap of objects that can be successfully converted to json string using gson without extra wrapper of 'map's
Again, then use Java classes, not parse tree classes from the parser. It's unclear what you're now asking since the above produces exactly what you said you wanted.
To be clear: you either work with parse tree objects, and generate the JSON from the tree, or you work with Java classes and have Gson serialize them to JSON. You can easily generate a JsonElement from any Map using Gson.toJsonTree()
i'm trying to create a hashmap (that can be converted to json string using gson by some other external process). so basically i want to create such a hashmap, and not a different data structure.
3

This has to do with the internal implementation of JSONObject. The class itself has an instance field of type java.util.Map with the name map.

When you parse the String

{"sender":{"id":"test test"},"recipients":{"id":"test1 test1"} }

with JSONObject, you actually have 1 root JSONObject, two nested JSONObjects, one with name sender and one with name recipients.

The hierarchy is basically like so

JSONObject.map ->
    "sender" -> 
            JSONObject.map ->
                    "id" -> "test test",
    "recipients" ->
            JSONObject.map ->
                    "id" -> "test test1"

Gson serializes your objects by mapping each field value to the field name.


Listen to this man.

And this one.

1 Comment

In other words, don't mix JSON toolkits.
3

I'd a similar problem and I finally resolved it using json-simple.

HashMap<String, Object> object = new HashMap<String,Object>;

// Add some values ...

// And finally convert it
String objectStr = JSONValue.toJSONString(object);

Comments

0

You may try out the standard implementation of the Java API for JSON processing which is part of J2EE.

JsonObject obj = Json
    .createObjectBuilder()
    .add("first_name", "prod")
    .add("data", Json.createObjectBuilder()
    .add("sender", Json.createObjectBuilder().add("id", "test test"))
    .add("recipients", Json.createObjectBuilder().add("id", "test1 test1"))).build();

Map<String, Object> prop = new HashMap<String, Object>() {
    {
        put(JsonGenerator.PRETTY_PRINTING, true);
    }
};
JsonWriter writer = Json.createWriterFactory(prop).createWriter(System.out);
writer.writeObject(obj);
writer.close();

The output should be:

{
    "first_name":"prod",
    "data":{
        "sender":{
            "id":"test test"
        },
        "recipients":{
            "id":"test1 test1"
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.