2014-12-06 53 views
4

我有原始JSON字符串这样,其中我有键和值,如下所示 -如何使用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 
} 

现在我需要做的是,我要代表键值对为SH拥有以下。如果任何值是字符串数据类型(如键值u),则用双引号表示它的值,否则不用双引号表示它的值。 country_id的含义值不会在String双引号中,因为它是一个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(); 
      Map<String, Object> jsonIn = gson.fromJson(data, type); 
      Map<String, Object> jsonOut = new HashMap<String, Object>(); 

      Set<String> keys = jsonIn.keySet(); 
      for (String key : keys) { 
       Object value = jsonIn.get(key); 
       if (value instanceof Map) { 
        Map<?, ?> mapValue = (Map<?, ?>) value; 
        for (Map.Entry<?, ?> entry : mapValue.entrySet()) { 
         jsonOut.put(key, entry.getValue()); 
        } 
       } else { 
        jsonOut.put(key, value); 
       } 
      } 

      // System.out.println(jsonOut); 

      String json = gson.toJson(jsonOut); 
      System.out.println(json); 

     } 
    } 

以上代码工作正常。唯一不起作用的是 - 当我尝试将jsonOut映射到JSON序列化时,那么一些键值无法正确显示。例如country_idtimestamp这两个关键值是错误的。

所以现在我的JSON是越来越印制这样的 - 你所看到的,country_id值是3.0,而不是它应该是3.同样的timestamp值1.417823759555E12相反,它应该是1417823759555

{ 
    "u": "1235", 
    "p": "2047935", 
    "client_id": "5", 
    "origin":null, 
    "item_condition":null, 
    "country_id": 3.0,    // this is different value 
    "timestamp": 1.417823759555E12, // and this is different value 
    "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 
} 

我该怎么做,我在做什么错?

+1

据推测当GSON读取传入的数据它曾经双人间一切。要强制使用所需的类型,您需要修改'instanceof Map'情况的逻辑。基本上,提取键和值,然后在键值上有一个“开关”来为新类型分配数字。 – 2014-12-06 03:36:21

+0

如果可能的话,重新设计JSON格式 - 这是没有意义的补充,如“串”冗余信息在那里 - 值已经是一个字符串,那么为什么添加无用的装饰? – StaxMan 2014-12-06 05:01:39

+0

@StaxMan很抱歉,我现在无法更改JSON格式。我只需要坚持这种格式。任何建议我怎么能做到这一点? – john 2014-12-06 16:55:16

回答

1

GSON,默认情况下,使用Double用于映射任何JSON数。由于您没有明确说明Java映射(即你使用Object

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

GSON将使用其默认。

除非你指定的类型,这似乎很难在你的情况,因为你的JSON看起来充满活力,你需要让自己转换它添加到您的最终系列化收藏前。

+0

感谢您提供有用的信息,你能提供一个例子,我该怎么做,手动吗? – john 2014-12-06 05:44:05

+0

在我的代码中,我猜是导致问题的线路是这样的 - “Map jsonIn = gson.fromJson(data,类型);'。当我尝试将JSON序列化到一个Map时,它将转换为double值。 – john 2014-12-06 16:19:49

+0

他在原始JSON中具有确切类型。 – 2014-12-07 00:35:00

0

轻微改写:

 for (String key : keys) { 
      Object value = jsonIn.get(key); 
      if (value instanceof Map) { 
       Map<?, ?> mapValue = (Map<?, ?>) value; 
       for (Map.Entry<?, ?> entry : mapValue.entrySet()) { 
        Double oldValue = (Double) entry.getValue(); 
        Object newValue; 
        switch(entry.getKey()) { 
         case "int": 
          newValue = Integer.valueOf(oldValue.intValue()); 
          break; 
         case "long": 
          newValue = Long.valueOf(oldValue.longValue()); 
          break; 
         case "string": 
          newValue = oldValue; 
          break; 
         default: 
          newValue = "Error -- could not translate"; 
        } 
        jsonOut.put(key, newValue); 
       } 
      } else { 
       jsonOut.put(key, value); 
      } 
     } 
相关问题