Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preserve data types of a particular key in JSON Object using GSON?

I have my original JSON String like this in which I have key and value as shown below -

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

As an example, one key is "u" and its value is -

{
    "string":"1235"
}

Similarly another key is "country_id" and its value is -

{
    "int":3
}

Now what I need to do is, I need to represent key value pair as shown below. If any value is string data type (like value for key u), then represent it's value in double quotes, otherwise don't represent it's value in double quotes. Meaning value of country_id won't be in String double quotes since it is an 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

And then I need to make another json string which should look like this -

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

So I started my approach like this and came with below code -

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

        }
    }

Above code is working fine. Only thing which is not working is - when I try to serialize jsonOut map to a JSON, then some key values are not getting shown correctly. For example country_id and timestamp these two key values are wrong.

So right now my json is getting printed like this - You can see, value of country_id is 3.0 instead it should be 3. Similarly value of timestamp is 1.417823759555E12 instead it should be 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
}

so ny new json should print out like this -

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

How can I do this and what wrong I am doing?

like image 721
john Avatar asked Dec 06 '14 03:12

john


People also ask

What does GSON toJson do?

Introduction. Gson is the main actor class of Google Gson library. It provides functionalities to convert Java objects to matching JSON constructs and vice versa. Gson is first constructed using GsonBuilder and then toJson(Object) or fromJson(String, Class) methods are used to read/write JSON constructs.


1 Answers

Gson, by default, uses Double for mapping any JSON number. Since you haven't explicitly stated the Java mapping (ie. you've used Object)

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

Gson will use its default.

Unless you specify the exact type, which seems to be difficult in your case since your JSON seems dynamic, you'll need to make the conversion yourself before adding it to your final serialized collection.

like image 151
Sotirios Delimanolis Avatar answered Sep 23 '22 03:09

Sotirios Delimanolis