Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moshi incorrectly deserializes an integer into a double-value #192

Closed
sqrt-1764 opened this issue Sep 22, 2016 · 7 comments
Closed

Moshi incorrectly deserializes an integer into a double-value #192

sqrt-1764 opened this issue Sep 22, 2016 · 7 comments

Comments

@sqrt-1764
Copy link

sqrt-1764 commented Sep 22, 2016

I am deserializing a map with name/value pairs where the values can have any value-type. So no class with members of a defined type can be given to deserialize into.

I can deserialize into a Map<String,Object> (the only solution), but then all numbers are deserialized into doubles. The underlying problem is that integers are wrongly convertet to doubles.

A simple call to

moshi.adapter(Object.class).fromJson("1234")

demonstrates this. Here a double is returned, whereas the argument describes an integer.

@JakeWharton
Copy link
Member

JSON only has numbers. Not integers or doubles. And since numbers can have decimals they are always represented as doubles in Java.

@swankjesse
Copy link
Member

Yep! And if you really want, you can get a Map<String, Integer> like so:

JsonAdapter<Map<String, Integer>> adapter
    = moshi.adapter(Types.newParameterizedType(Map.class, String.class, Integer.class);
adapter.fromJson("{\"a\": 1234}")

@sqrt-1764
Copy link
Author

sqrt-1764 commented Sep 22, 2016

The pure JSON does not distinguish between integers and doubles, correct. But I see a subtle difference in the notation that can be used to separate integers from doubles. And converting from Java to JSON with moshi this is currently already implemented:

              Java -> Json

double: 1234.567 -> 1234.567
double: 1234.0 -> 1234.0
long: 1234 -> 1234

So an integer can be identified by a missing decimal point. Otherwise the 2nd and 3rd line would have to be converted the same.

So the conversion back would be: If it is a number and there is no decimal point convert to long otherwise to double.

The problem that I try to solve is to synchronize abitrary datatables between systems with JSON. So I know that the names of the fields are strings, but I know nothing about the types of the fields. And as integers can not always be correctly mapped to doubles I have to distinguish between those types.

At the moment I don't know how to write an adapter that returns more than one type. So I would have to use Object as return type. But what would be the input type? (I refer to the examples in the documentation with the @FromJSON annotations)
The solution from @swankjesse does not solve the problem as I can not tell which field has which type.

@swankjesse
Copy link
Member

You can read numbers in Moshi as strings and decode to your preferred format using your preferred rules.

@sqrt-1764
Copy link
Author

Maybe I did not get your point.
I can not map the numbers to strings because I would lose the difference between numbers and strings then.
So how to intercept the parser before he converts the numbers and return the appropriate type from there? Currently I do not see how to accomplish this with JsonAdapters.
I opened a question in StackOverflow for this: [http://stackoverflow.com/questions/39658090/how-to-distinguish-long-and-double-values-when-deserializing-with-moshi]

@fmachado
Copy link

I've a scenario where I cannot enforce a type so, things like

JsonAdapter<Map<String, Integer>> adapter = ...

are not a viable option.

Would be possible to handle non-floating point numbers as int, long or BigInteger as Jackson does?

@NightlyNexus
Copy link
Contributor

In Moshi 1.6.0, you will be able to do this.

https://github.com/square/moshi/pull/316/files#diff-377a789dd290133f2491a9d6b5d3bad8R221

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants