Reputation: 1566
Take for example this short JSON taken as a String
from an API response using RestAssured
:
{
"id": "4d27afb18bfa4eb5917beee9aaddfa76",
"hedgeId": 205598,
"sellCurrency": "USD",
"buyCurrency": "EUR",
"buyAmount": 473935.00,
"sellAmount": 585538.30,
}
Whenever I do JSONObject foo = new JSONObject(thatStringAbove);
, this instance is created:
{
"hedgeId": 205598,
"buyAmount": 473935,
"sellAmount": 585538.3,
"id": "4d27afb18bfa4eb5917beee9aaddfa76",
"sellCurrency": "USD",
"buyCurrency": "EUR"
}
Notice the trailing zeros from amount nodes are stripped. This looks like a bug to me but does anyone know of a workaround / solution how to prevent this from happening?
Few notes:
Maven dependency:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20170516</version>
</dependency>
Appreciate the help!
Upvotes: 0
Views: 2130
Reputation: 7286
You won't be able to do this with the org.json library. It deliberately strips trailing zeros during serialisation.
From the relevant method JSONObject.numberToString()
:
public static String numberToString(Number number) throws JSONException {
if (number == null) {
throw new JSONException("Null pointer");
}
testValidity(number);
// Shave off trailing zeros and decimal point, if possible.
String string = number.toString();
if (string.indexOf('.') > 0 && string.indexOf('e') < 0
&& string.indexOf('E') < 0) {
while (string.endsWith("0")) {
string = string.substring(0, string.length() - 1);
}
if (string.endsWith(".")) {
string = string.substring(0, string.length() - 1);
}
}
return string;
}
I'd suggest using a more customisable library like jackson or gson.
Gson will respect the scale on the number, allowing you to perform your round trip without losing trailing zeros:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonObject jsonObject = gson.fromJson(in, JsonObject.class);
System.out.println(gson.toJson(jsonObject));
Output:
{
"id": "4d27afb18bfa4eb5917beee9aaddfa76",
"hedgeId": 205598,
"sellCurrency": "USD",
"buyCurrency": "EUR",
"buyAmount": 473935.00,
"sellAmount": 585538.30
}
It will also do mapping to Objects if you desire.
Upvotes: 1
Reputation: 367
One Way is To Use String Instead of Number e.g
{
"buyAmount": "473935.00",
"sellAmount":"585538.30",
}
If You are Using BigDecimal
Use toPlainString
method to avoid removing trailing Zeros
Upvotes: 0