Java: org.json.JSONObject - 创建一个新实例会从大的小数中删除尾随零

Java: org.json.JSONObject - creating a new instance removes trailing zeros from big decimals

例如,使用 RestAssured:

从 API 响应中将此短 JSON 视为 String
{
    "id": "4d27afb18bfa4eb5917beee9aaddfa76",
    "hedgeId": 205598,
    "sellCurrency": "USD",
    "buyCurrency": "EUR",
    "buyAmount": 473935.00,
    "sellAmount": 585538.30,
}

每当我执行 JSONObject foo = new JSONObject(thatStringAbove); 时,都会创建此实例:

{
  "hedgeId": 205598,
  "buyAmount": 473935,
  "sellAmount": 585538.3,
  "id": "4d27afb18bfa4eb5917beee9aaddfa76",
  "sellCurrency": "USD",
  "buyCurrency": "EUR"
}

注意数量节点的尾随零被去除。这对我来说像是一个错误,但有谁知道如何防止这种情况发生的解决方法/解决方案吗?

几点注意事项:

  • 我想使用相同的库来解决这个问题 (org.json)
  • 如果可能的话,我想从字符串构造实例,就像我目前正在做的那样

    Maven 依赖:

            <dependency>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
                <version>20170516</version>
            </dependency>
    

    感谢帮助!

  • 您将无法使用 org.json 库执行此操作。它在序列化期间故意去除尾随零。

    来自相关方法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;
    }
    

    我建议使用更可自定义的库,例如 jacksongson.

    Gson 会遵守数字的比例,允许您在不丢失尾随零的情况下执行往返:

    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    JsonObject jsonObject = gson.fromJson(in, JsonObject.class);
    System.out.println(gson.toJson(jsonObject));
    

    输出:

    {
        "id": "4d27afb18bfa4eb5917beee9aaddfa76",
        "hedgeId": 205598,
        "sellCurrency": "USD",
        "buyCurrency": "EUR",
        "buyAmount": 473935.00,
        "sellAmount": 585538.30
    }
    

    如果您愿意,它还会映射到对象。

    一种方法是使用字符串而不是数字,例如

    {
    "buyAmount": "473935.00",
    "sellAmount":"585538.30",
    } 
    

    如果您正在使用 BigDecimal 使用 toPlainString 方法避免删除尾随零