简体   繁体   中英

How to convert map of JSON objects to JSON using GSON in Java?

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 (eg using gson to convert the map).

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 JSONObject s, 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.

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);

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);

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"
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM