Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Gson parse an Integer as a Double?

Tags:

java

json

gson

A complex json string and I want to convert it to map, I have a problem.

Please look at this simple test:

public class Test {

    @SuppressWarnings("serial")
    public static void main(String[] args) {
        Map<String, Object> hashMap = new HashMap<String, Object>();
        hashMap.put("data", "{\"rowNum\":0,\"colNum\":2,\"text\":\"math\"}");

        Map<String,Object> dataMap = JsonUtil.getGson().fromJson(
                hashMap.get("data").toString(),new TypeToken<Map<String,Object>>() {}.getType());

        System.out.println(dataMap.toString());

    }
}

result:
console print : {rowNum=0.0, colNum=2.0, text=math}
Int is converted to Double;
Why does gson change the type and how can I fix it?

like image 658
andy.hu Avatar asked Aug 17 '17 12:08

andy.hu


People also ask

How can you prevent Gson from expressing integers as floats?

One option is to define a custom JsonDeserializer, however better would be to not use a HashMap (and definitely don't use Hashtable!) and instead give Gson more information about the type of data it's expecting. Show activity on this post. Show activity on this post. Show activity on this post.

How does Gson from JSON work?

Gson can work with arbitrary Java objects including objects for which you do not have the source. For this purpose, Gson provides several built in serializers and deserializers. A serializer allows to convert a Json string to corresponding Java type. A deserializers allows to convert from Java to a JSON representation.

How does Google Gson work?

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.

Why do we need Gson?

Overview. Google's Gson library provides a powerful framework for converting between JSON strings and Java objects. This library helps to avoid needing to write boilerplate code to parse JSON responses yourself. It can be used with any networking library, including the Android Async HTTP Client and OkHttp.


2 Answers

Gson is a simple parser. It uses always Double as a default number type if you are parsing data to Object.

Check this question for more information: How to prevent Gson from expressing integers as floats

I suggest you to use Jackson Mapper. Jackson distinguish between type even if you are parsing to an Object:

  • "2" as Integer
  • "2.0" as Double

Here is an example:

Map<String, Object> hashMap = new HashMap<String, Object>();
hashMap.put("data", "{\"rowNum\":0,\"colNum\":2,\"text\":\"math\"}");
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String, Object>> typeRef = new TypeReference<HashMap<String, Object>>() {};

HashMap<String, Object> o = mapper.readValue(hashMap.get("data").toString(), typeRef);

maven:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>
like image 181
dieter Avatar answered Sep 19 '22 17:09

dieter


JSON makes no distinction between the different type of numbers the way Java does. It sees all kind of numbers as a single type.

That the numbers are parsed as a Double is an implementation detail of the Gson library. When it encounters a JSON number, it defaults to parsing it as a Double.

Instead of using a Map, it would be better to define a POJO that encapsulates all fields of the JSON structure. This makes it much easier to access the data afterwards and the numbers are automatically parsed as an Integer.

class Cell {
    private Integer rowNum;
    private Integer colNum;
    private String text;
}

public static void main(String[] args) throws Exception {
    Map<String, Object> hashMap = new HashMap<String, Object>();
    hashMap.put("data", "{\"rowNum\":0,\"colNum\":2,\"text\":\"math\"}");

    Cell cell = new Gson().fromJson(hashMap.get("data").toString(), Cell.class);
    System.out.println(cell);
}
like image 34
Luciano van der Veekens Avatar answered Sep 17 '22 17:09

Luciano van der Veekens