【问题标题】:Java: org.json.JSONObject - creating a new instance removes trailing zeros from big decimalsJava:org.json.JSONObject - 创建一个新实例从大小数中删除尾随零
【发布时间】:2018-04-04 03:00:40
【问题描述】:

以这个简短的 JSON 为例,它是使用 RestAssured 的 API 响应中的 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>
    

    感谢您的帮助!

  • 【问题讨论】:

    • 您正在序列化为 JSON number 类型,它始终是浮点数并且没有精度。如果你想让它保持格式,你需要使用一个字符串。

    标签: java json rest-assured web-api-testing org.json


    【解决方案1】:

    您将无法使用 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
    }
    

    如果你愿意,它也会映射到对象。

    【讨论】:

    • 感谢您提供此信息。希望我早点选择gson。现在使用它需要一些工作和时间。将等待其他答案,如果没有其他答案,将接受。
    • 你可以分叉库并更新numberToString
    【解决方案2】:

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

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

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

    【讨论】:

    • 很遗憾,我无法修改规范。数据将来自已定义的 API 响应。
    猜你喜欢
    • 1970-01-01
    • 2012-07-01
    • 2012-07-02
    • 2011-05-30
    • 2017-03-01
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多