java - 如何通过保留键的数据类型将json序列化为另一个json?

标签 java json string serialization gson

我有像这样的原始 JSON 字符串,其中有键和值,如下所示 -

{
  "u":{
     "string":"1235"
  },
  "p":"2047935",
  "client_id":{
     "string":"5"
  },
  "origin":null,
  "item_condition":null,
  "country_id":{
     "int":3
  },
  "timestamp":{
     "long":1417823759555
  },
  "impression_id":{
     "string":"2345HH*"
  },
  "is_consumerid":true,
  "is_pid":false
}

举个例子,一个键是“u”,它的值是-

{
    "string":"1235"
}

类似地,另一个键是“country_id”,其值为-

{
    "int":3
}

现在我需要做的是,我需要表示键值对,如下所示。如果任何值是字符串数据类型(例如键 u 的值),则用双引号表示它的值,否则不要用双引号表示它的值。 Country_id 的含义值不会出现在字符串双引号中,因为它是一个 int。

"u": "1235"
"p": "2047935"
"client_id": "5"
"origin":null
"item_condition":null
"country_id": 3 // I don't have double quotes here around 3 since country_id was int that's why
"timestamp": 1417823759555
"impression_id": "2345HH*"
"is_consumerid": true
"is_pid": false

然后我需要制作另一个 json 字符串,它应该如下所示 -

{
    "u": "1235",
    "p": "2047935",
    "client_id": "5",
    "origin":null,
    "item_condition":null,
    "country_id": 3,
    "timestamp": 1417823759555,
    "impression_id": "2345HH*",
    "is_consumerid": true,
    "is_pid": false
}

所以我从下面的代码开始,但无法理解我应该进一步做什么?

    String response = "original_json_string";
    Type type = new TypeToken<Map<String, Object>>() {}.getType();

    JsonObject jsonObject = new JsonParser().parse(response).getAsJsonObject();

    for (Map.Entry<String, JsonElement> object : jsonObject.entrySet()) {
        if (object.getValue() instanceof JsonObject) {
            String data = object.getValue().toString();
            // now not sure what should I do here?

        }
    }

序列化后我的新 json 应该像这样打印出来。

{
    "u": "1235",
    "p": "2047935",
    "client_id": "5",
    "origin":null,
    "item_condition":null,
    "country_id": 3,
    "timestamp": 1417823759555,
    "impression_id": "2345HH*",
    "is_consumerid": true,
    "is_pid": false
}

实现这一目标的最佳方法是什么?

最佳答案

请注意,我对 Gson 还不太有经验,所以可能有最简单的方法来做到这一点。这个解决方案也是在我们之前的讨论之后提出的。

基本上,问题是获取 json 文件中所需的类型(由 addEntry 方法完成),并且每个 @event 键应该有自己的 JSON 字符串(由 完成)计算Json)。由于只有两个嵌套级别,因此这样做就可以了。否则,递归方法就可以解决问题。

因此,如果只有一个嵌套级别,则应该迭代 JsonObject 的其他条目。对于每个条目,computeJson 都会在列表中添加一个新的 Json 条目,该条目对应于每个 @event 键。

public class Test {
    public static void main(String[] args) throws Exception {   
        List<String> output = new ArrayList<>();
        JsonObject jsonObject = new JsonParser().parse(new FileReader("myJson.json")).getAsJsonObject();
        for (Map.Entry<String, JsonElement> object : jsonObject.entrySet()) {
            if (object.getValue() instanceof JsonObject) {
                output.add(computeJson((JsonObject)object.getValue()));
            }
        }
        System.out.println(output);
    }

    private static String computeJson(JsonObject source) {
        JsonObject output = new JsonObject();
        for (Map.Entry<String, JsonElement> object : source.entrySet()) {
            if (object.getValue() instanceof JsonObject) {
                for(Map.Entry<String, JsonElement> entry : ((JsonObject)object.getValue()).entrySet()) {
                    addEntry(object.getKey(), output, entry);
                }
            } else {
                addEntry(object.getKey(), output, object);
            }
        }
        Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
        return gson.toJson(output);
    }

    private static void addEntry(String key, JsonObject output, Map.Entry<String, JsonElement> object) {
        switch(object.getKey().toLowerCase()) {
            case "string":
                output.addProperty(key, object.getValue().getAsString());
                break;
            case "int":
                output.addProperty(key, object.getValue().getAsInt());
                break;
            case "long":
                output.addProperty(key, object.getValue().getAsLong());
                break;
            //add other primitive cases
            default:
                output.add(key, object.getValue());
        }
    }
}

关于java - 如何通过保留键的数据类型将json序列化为另一个json?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27329227/

相关文章:

java - JobOperator 无法实例化

java - 在 Spring 中缓存带有数组参数的方法

c# - 类似于 F#(或 C#)中 python 的三重引号?

java - 在java中,如何替换cookie值中的整数值?

Java IOException 错误/表达式的非法开始

java - 使用正则表达式一次性替换主题标签

json - 在Swift 3中正确解析JSON

javascript - Javascript 中的广度优先搜索

json - Uncaught SyntaxError : Unexpected token : in JSON response

python - 我怎样才能让我的程序打印 float ?