【问题标题】:Gson to json add map dynamically to objectGson to json 动态添加映射到对象
【发布时间】:2014-12-18 07:11:30
【问题描述】:

我有一个对象,它表示我想序列化为 json 的事件,如果更容易使用 gson 或其他库。

我想在 json 中添加以下类型的字段:

private Map<String, String> additionalProperties;

还有另一个用例:

private Map<String, Object> additionalProperties;

但是如果我在 Event 对象中添加附加属性,并以正常方式构建 Gson:

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

它会看起来像这样:

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

我只想以以下形式附加到事件对象:

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

这是一个示例输出 - 添加的附加属性是对象“z”和对象“广告商”:

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

这是它目前的样子:

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

【问题讨论】:

  • 为了澄清你的问题,你分享了一个 json 文本(编辑你的帖子)。但我不明白它应该向我们展示什么。为了更清楚,你能分享2个json,一个告诉我们你有什么,另一个告诉我们你想要什么。
  • OK 没问题 - 完成!

标签: java json serialization jackson gson


【解决方案1】:

解决这个问题的最佳方法是使用动态添加属性的框架,但如果没有这个,您可以将其他属性添加到您的 Event 对象(包括 @JsonIgnore 以便它不是最终 json 的一部分),从附加属性创建一个新的 JSONObject 并将其合并到事件 JSONObject 中,然后再序列化为 json。这样,附加属性会动态添加到结果事件输出中。

在事件类中:

@JsonIgnore
    private Map<String, Object> additionalProperties;

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

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

合并两个 JSONObject 的函数:

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

将两个对象放在一起:

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

【讨论】:

    【解决方案2】:

    如果你的 Event 类是这样的;

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

    你正在打电话;

    String json = gson.toJson(event);
    

    预期和有效的输出将是:

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

    如果你想要这样的输出;

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

    你可以打电话;

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

    我只想在下面附加到事件对象 形式:

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

    这样,如果您将该值直接附加到 json 对象,它将不是有效的 json 变量。如果您想要的 json 值在http://jsonviewer.stack.hu/ 处有效或无效,您最好尝试一下

    【讨论】:

    • 感谢您的回答 - 这是我已经考虑过的问题,但我还有其他变量,我想在 Event 对象中序列化为 json 并且 toJson 不接受对象的两个参数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    相关资源
    最近更新 更多