SpringBoot Fastjson解析多层嵌套复杂Json字符串

1 []中括号代表的是一个数组;
2 {}大括号代表的是一个对象
3 双引号“”表示的是属性值
4 冒号:代表的是前后之间的关系,冒号前面是属性的名称,后面是属性的值,这个值可以是基本数据类型,也可以是引用数据类型。

Fastjson中的经常调用的方法

parseObject(String text);: 把JSON文本parse成JSONObject
parse(String text);: 把JSON文本parse为JSONObject或者JSONArray
key 必须是字符串,value 可以是合法的 JSON 数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)
value如果是字符串,用jsonobj.getString("key")获取
value如果是数  字,用jsonobj.getIntValue("key"),jsonobj.getFloatValue("key"),jsonobj.getInteger("key")等基本数据类型及其包装类的方法获取
value如果是布尔值,用jsonobj.getBoolean("key"),jsonobj.getBooleanValue("key")获取
value如果是数  组,用jsonobj.getJSONArray("key")获取
value如果是Object对象,用jsonobj.get("key"),获取
value如果是JSONObject对象,用jsonobj.getJSONObject("key")获取
{
    "code":"200",
   
在使用 `JSON.toJSONString` 方法时,如果抛出 `IllegalArgumentException` 异常,并提示 `Comparison method violates its general contract!`,这通常与 Java 的排序比较逻辑有关[^1]。虽然 `JSON.toJSONString` 本身并不直接涉及排序操作,但在某些情况下(例如序列化包含自定义排序逻辑的对象集合时),FastJSON 可能会触发内部排序机制。 ### 常见原因分析 #### 1. 自定义 `Comparator` 不符合规范 当对象集合中使用了自定义的 `Comparator`,而该比较器未遵循以下规则时,会导致此异常: - **对称性**:对于任意两个对象 `a` 和 `b`,`compare(a, b)` 的结果应为 `compare(b, a)` 的相反数。 - **传递性**:对于任意三个对象 `a`、`b` 和 `c`,如果 `compare(a, b) <= 0` 且 `compare(b, c) <= 0`,则 `compare(a, c) <= 0`。 - **一致性**:多次调用 `compare()` 应返回相同的结果,除非对象状态发生改变。 若 FastJSON 在序列化过程中尝试对集合进行排序(如 `TreeSet` 或使用了 `sorted()` 的流),而该排序逻辑依赖于不合规的比较器,则会抛出此异常。 #### 2. 使用了 `BigDecimal` 字段 在某些版本的 JDK 中,`BigDecimal` 的自然排序可能因精度问题导致违反排序契约。例如: ```java BigDecimal a = new BigDecimal("1.0"); BigDecimal b = new BigDecimal("1"); ``` 两者数值相等,但 `compareTo()` 可能返回非零值,从而引发异常[^1]。 --- ### 解决方案 #### 1. 检查并修正自定义 `Comparator` 确保所有用于排序的 `Comparator` 实现都严格遵守排序契约。可以通过以下方式验证: ```java List<Sku> list = ...; list.sort((o1, o2) -> { // 确保比较逻辑无歧义、无副作用 return Integer.compare(o1.getPrice(), o2.getPrice()); }); ``` #### 2. 避免在序列化前自动排序 在使用 `JSON.toJSONString` 之前,避免对集合执行可能触发排序的操作。例如,不要将集合包装为 `TreeSet` 后再传入 FastJSON: ```java // 不推荐 Set<Sku> sortedSet = new TreeSet<>(customComparator); sortedSet.addAll(cartSkuList); String json = JSON.toJSONString(sortedSet); // 可能触发异常 ``` #### 3. 替换 `BigDecimal` 比较逻辑 如果对象中包含 `BigDecimal` 字段,在比较时建议使用其 `stripTrailingZeros().toPlainString()` 方法进行标准化后再比较,或改用 `equals()` 判断数值是否相等。 #### 4. 升级 JDK 版本 部分 JDK 版本存在 `BigDecimal.compareTo()` 的实现缺陷,升级至最新稳定版可规避此类问题。 --- ### 示例代码 修正后的安全序列化方式如下: ```java List<Sku> result = CartService.filterSkus(cartSkuList, sku -> sku.getSkuPrice() > 1000); // 显式排序前检查比较逻辑 result.sort(Comparator.comparingInt(Sku::getSkuPrice)); System.out.println(JSON.toJSONString(result, true)); // 安全序列化 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

地表最强菜鸡

你的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值