Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Gson from expressing integers as floats

Tags:

java

android

gson

Gson has some odd behavior when I try to convert a string to json. The code below transforms string draft into json responses. Is there a way to prevent gson from adding the '.0 to all integer values?

ArrayList<Hashtable<String, Object>> responses; Type ResponseList = new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType(); responses = new Gson().fromJson(draft, ResponseList);  draft: [ {"id":4077395,"field_id":242566,"body":""},   {"id":4077398,"field_id":242569,"body":[[273019,0],[273020,1],[273021,0]]},   {"id":4077399,"field_id":242570,"body":[[273022,0],[273023,1],[273024,0]]} ]  responses: [ {id=4077395.0, body=, field_id=242566.0},   {id=4077398.0, body=[[273019.0, 0.0], [273020.0, 1.0], [273021.0, 0.0]], field_id=242569.0},   {id=4077399.0, body=[[273022.0, 0.0], [273023.0, 1.0], [273024.0, 0.0]], field_id=242570.0} ] 
like image 425
Mark Murphy Avatar asked Mar 19 '13 18:03

Mark Murphy


People also ask

Should Gson objects be static?

The Gson object is explicitly safe to use from multiple threads, as it doesn't keep any internal state, so yes, declare a private static final Gson GSON = new Gson(); , or even make it public .

Does Gson work with private fields?

In this example you'll see how the Gson library handles the object fields. For object fields to be serialized into JSON string it doesn't need to use any annotations, it can even read private fields.

Does Gson serialize static fields?

gson. GsonBuilder works this way for the same reason. Static fields are not serializable because static fields are class variables , they are not specific for particular instance of that class.

Does Gson ignore extra fields?

3. Deserialize JSON With Extra Unknown Fields to Object. As you can see, Gson will ignore the unknown fields and simply match the fields that it's able to.


1 Answers

You're telling Gson it's looking for a list of maps of Strings to Objects, which essentially says for it to make a best guess as to the type of the Object. Since JSON doesn't distinguish between integer and floating point fields Gson has to default to Float/Double for numeric fields.

Gson is fundamentally built to inspect the type of the object you want to populate in order to determine how to parse the data. If you don't give it any hint, it's not going to work very well. 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.

class Response {   int id;   int field_id;   ArrayList<ArrayList<Integer>> body; // or whatever type is most apropriate }  responses = new Gson()             .fromJson(draft, new TypeToken<ArrayList<Response>>(){}.getType()); 

Again, the whole point of Gson is to seamlessly convert structured data into structured objects. If you ask it to create a nearly undefined structure like a list of maps of objects, you're defeating the whole point of Gson, and might as well use some more simplistic JSON parser.

like image 131
dimo414 Avatar answered Sep 21 '22 17:09

dimo414