James Smyth
James Smyth

Reputation: 55

Gson to json add map dynamically to object

I have an object that represents an event that I would like to serialize into json, using gson or another library if that works easier.

I want to add the following type of field to the json:

private Map<String, String> additionalProperties;

And also in another use case:

private Map<String, Object> additionalProperties;

But if I add additionalProperties to the Event object, and build Gson in the normal way:

Gson gson = BUILDER.create();
String json = gson.toJson(event);

It will appear like so:

additional_properties: {"value1":1,"value2":"abc"}

I would simply like to append to the event object in the following form:

{"value1":1,"value2":"abc"}

Here is an example output- the additional properties added are the object 'z' and the object 'advertiser':

{"organisationid":"2345612ß","projectid":"12345678",
"place":{"placeId":"2345","last_place":"123-3"},
"advertiser":{"advertiserId":"2345a","code":"a123-3"},
"user":{"isY":false,"isHere":false,"isBuyer":false},
"x":{"identifier":"SHDG-28CHD"},
"z":{"identifier":"abcSHDG-28CHD"},
"event_type":"x_depart"}

Here is what it currently looks like:

{"organisationid":"2345612ß","projectid":"12345678",
"place":{"placeId":"2345","last_place":"123-3"},
additionalproperty: {"advertiser":{"advertiserId":"2345a","code":"a123-3"},
"user":{"isY":false,"isHere":false,"isBuyer":false},
"x":{"identifier":"SHDG-28CHD"},
additionalproperty: {"z":{"identifier":"abcSHDG-28CHD"}},
"event_type":"x_depart"}

Upvotes: 3

Views: 2518

Answers (2)

santdrog
santdrog

Reputation: 98

The best way to solve this would be with a framework for adding properties dynamically, but without this, you could add the additional properties to your Event object (include @JsonIgnore so that it is not part of the final json), create a new JSONObject from the additional properties and merge it to the event JSONObject before serializing to json. This way the additional properties are added dynamically to the resulting Event output.

In the Event class:

@JsonIgnore
    private Map<String, Object> additionalProperties;

    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    public void setAdditionalProperties(Map<String, Object> additionalProperties) {
        this.additionalProperties = additionalProperties;
    }

A function to merge two JSONObjects:

public static JSONObject mergeObjects(JSONObject source, JSONObject target) throws JSONException {
    for (String key: JSONObject.getNames(source)) {
            Object value = source.get(key);
            if (!target.has(key)) {
                // new value for "key":
                target.put(key, value);
            } else {
                // existing value for "key" - recursively deep merge:
                if (value instanceof JSONObject) {
                    JSONObject valueJson = (JSONObject)value;
                    deepMerge(valueJson, target.getJSONObject(key));
                } else {
                    target.put(key, value);
                }
            }
    }
    return target;
}

Putting the two objects together:

 String jsonAdd = mapper.writeValueAsString(additional);
 String jsonEvent = mapper.writeValueAsString(event);

 JSONObject jsonAddObj = new JSONObject(jsonAdd);
 JSONObject JsonEventObj = new JSONObject(jsonEvent);
 JSONObject finalJson = Merge.deepMerge(jsonAddObj, JsonEventObj);

Upvotes: 2

Devrim
Devrim

Reputation: 15533

If your Event class is something like;

class Event {
    private Map<String, Object> additionalProperties;
}

and you are calling;

String json = gson.toJson(event);

The ecpected and the valid output would be:

{"additionalProperties":{"value1":1,"value2":"abc"}}

If you want an output such as;

{"value1":1,"value2":"abc"}

You can call;

String json = gson.toJson(event.additionalProperties);

I would simply like to append to the event object in the following form:

{"value1":1,"value2":"abc"}

That way it won't be a valid json variable if you append that value directly to a json object. You should better try if the json value you want is valid or not at http://jsonviewer.stack.hu/

Upvotes: 0

Related Questions