play-json icon indicating copy to clipboard operation
play-json copied to clipboard

Long can't be represented as JSON number

Open bigaru opened this issue 6 years ago • 7 comments

Issue

If a Java/Scala Long value is converted to JSON, then naturally I expect that it will be represented as JSON number. But counter-intuitively the Long value can be too large for javascript and therefore, it isn't good idea to represent as JSON number.

For an example you can take Long.MaxValue and try it out with browser's console. In my case the last four digits fail.

>>> var longVal = {"count" : 9223372036854775807}
>>> longVal 
Object { count: 9223372036854776000 }

Actual Behavior

Play-json represents Long as JSON number.

println("[play-json] " + Json.toJson(Long.MaxValue) )
[play-json] 9223372036854775807

Expected Behavior

As μPickle the Long value should be represented as JSON string.

println("[upickle] " + write(Long.MaxValue) )
[upickle] "9223372036854775807"

Tested Version

  • play-json 2.6.7
  • upickle 0.6.6
  • firefox 60.0.2

bigaru avatar Jun 28 '18 21:06 bigaru

If you want this behavior, you can define your own implicit val stringLong: Writes[Long] = l => JsString(l.toString) in scope.

dhoepelman avatar Sep 23 '18 17:09 dhoepelman

Hi,

I think string formatter could be added as suggested, but keeping the current behaviour as the default one.

Altering the default behaviour first need discussion.

Best regards

cchantep avatar Sep 24 '18 10:09 cchantep

What about adding it to the library as an extra import, document it and let people know that they can enable it by bringing in the import?

We keep the old behaviour of course, but we offer the option to enable the new Format when desired.

octonato avatar Sep 25 '18 08:09 octonato

sry for late response I agree with @renatocaval

I think it's important to point out somewhere in documentation about the problem when JSON is directly consumed by JavaScript.

When I used Play in last project in combination with React, the frontend developer was not aware of this problem. He even argued if there was a problem, then Play's JSON converter would not transform Java Long into JSON number. But as it seems, it's bit more complicated.

JSON number representation of Java Long is not always a problem. It's only a problem if the JSON is later consumed by JavaScript as shown below.

# problematic cases
[Play] <----> [React]
[Play] <----> [Angular]
[Play] <----> [Any javascript endpoint]

// no problem
[Play] <----> [Android]
[Play] <----> [Endpoint written in a language which supports Integer64]

bigaru avatar Nov 22 '18 21:11 bigaru

@bigaru, would you like to send a PR for this?

octonato avatar Nov 22 '18 21:11 octonato

@renatocaval I'd like to provide a PR for this. (a wonderful chance to get to know Play's code)

Since I am not familiar with this repository and I am very busy at the moment, I estimate that it will take about 2 weeks, at most 4 weeks.

bigaru avatar Nov 23 '18 13:11 bigaru

No worries, take your time. :-)

And don't hesitate to ask for guidance if needed.

octonato avatar Nov 26 '18 08:11 octonato