12

Hi can i configure gson that he use int instead of double got data like:

{fn: chat, data: {roomId: 1, text: "Some brabble"}}

I got a PacketClass to deserialize it to:

public class DataPacket {
  private String fn;
  private Object p; // will be a StringMap
}

and decode like:

DataPacket pkg = gson.fromJson(message, DataPacket.class);

for better typehandling i got a data pojo for the DataPacket.p field for example:

public class ChatPacket {
  public int roomId;
  public String message;
  public String from;
  // getter & setter
}

to parse the data to the packet i use BeanMaps like (i removed error handling etc):

public Object getData(Class<?> pojoClass) {
  pojo = pojoClass.newInstance();
  BeanMap b = new BeanMap();
  b.setBean(pojo);
  b.putAll(this.p);
  pojo = b.getBean();
}

The problem is now that gson make the roomId: 1 to a double 1.0 in the StringMap and the beanmap try to parse it to an integer and throws a NumberFormatException, anyone got an idea how to fix this?

Thank You!

Kani
  • 810
  • 1
  • 19
  • 38
  • 3
    All numeric values in JSON are double-precision floating point. JSON has no integer type. – Daniel Pryden Aug 22 '12 at 06:11
  • I would count this as a major deficiency of the JSON specification. It ought to define a simple integer type and not leave this to varying implementations. (I'm running into this, too. The system I'm communicating with uses Gson and turns ints into floats, which don't convert back to ints since there's a loss of precision.) – Keith Robertson Jan 09 '13 at 12:59
  • Keith, I haven't noticed any loss of precision when doing the following: `final Long lTest = Math.round(doubleValue); Log.i("Test",String.valueOf(lTest));//decimal Log.i("Test",Long.toHexString(lTest));//hex` – Someone Somewhere Jan 08 '14 at 19:51
  • Dup of http://stackoverflow.com/questions/15507997/how-to-prevent-gson-from-expressing-integers-as-floats – Vadzim Jul 14 '15 at 15:37
  • You mean that is an duplicate of mine? – Kani Jul 15 '15 at 22:57
  • Or, try converting to Jackson – Kirby Dec 14 '16 at 04:43
  • @DanielPryden I would argue that JSON has/supports both integer and double types. If I supply a value of `1`, it's an integer and if I supply `1.0` it's a double. The existence of a decimal point in the value makes inferring the type extremely straightforward. It's not JSON that has this limitation, but GSON, which seems to be incapable of inferring the correct type based on the value, which is quite bewildering. – rmirabelle Mar 09 '22 at 22:35

1 Answers1

1

I think you could simply change your DataPacket class to

public class DataPacket {
  private String fn;
  private ChatPacket p; // will be a StringMap
}

(replace Object by ChatPacket) - if that suits into the rest of your application. Gson will then recognize the data types of the ChatPacket class and will trait the "1" as int.

EDIT (as you can't use full formatting features in comments :-( )

You can use a combination of Gson and it's low level helper JsonParser like this:

String testStr = "{fn: chat, data: {roomId: 1, message: \"Some brabble\"}}";
DataPacket dp = new Gson().fromJson(testStr, DataPacket.class); 
JsonParser parser = new JsonParser(); 
JsonElement e = parser.parse(testStr); 
ChatPacket cp = new Gson().fromJson(e.getAsJsonObject().getAsJsonObject("data"), ChatPacket.class);
Steffen Blass
  • 276
  • 1
  • 4
  • y but this is not dynamicly got much of the packets and i want to minify the process of create new packets. – Kani Aug 22 '12 at 06:22
  • Ok, got that point. What about changing Object to String - to have the "raw" json string in your DataPacket and add another String field that defines the class name of your transported data. You could then let another Gson-call with that dynamic class do the mapping of the inner class. – Steffen Blass Aug 22 '12 at 06:33
  • did that work does gson put the raw string into the string value? when this is true then its the solution, ill try it later thank you! – Kani Aug 22 '12 at 07:00
  • Gson won't do it "automagically" - but you can use a combination of Gson and it's low level helper JsonParser like this: `DataPacket dp = new Gson().fromJson(testStr, DataPacket.class); JsonParser parser = new JsonParser(); JsonElement e = parser.parse(testStr); ChatPacket cp = new Gson().fromJson(e.getAsJsonObject().getAsJsonObject("data"), ChatPacket.class);` – Steffen Blass Aug 22 '12 at 07:25