Fix issue #3293 and issue #3328 #3384
Open
+172
−77
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What this PR does / why we need it?
之前 Fastjson 2.0.53 是可以将非字符串形式的自动
toString()
, 后来 Fastjson 2.0.54 调整之后,就不支持了。我看了下,这次调整是为了修复 Issue #3264 。
如果只需要支持字符串形式的 key 的话,那么 #3264 其实也是无需修复的。
这次调整后,就导致部分key输出会附带额外的 单引号 或 双引号。
虽然
Map
具有非字符串形式 的 key 并不符合严格的 JSON 规范,但是在实际开发过程中,非字符串形式的 key 还是客观且普遍存在的。比如:
EnumMap
的 key 是一个枚举,这是一种比较常见的用法,如果要转换为字符串,就需要将所有数据额外转换并迁移到其他Map
类型。TreeMap<Integer, Object>
的 key 是一个整型,整型的排序规则和字符串也是不一样的,所以要保持相同的排序规则,也需要额外再多作一次转换,并且还不能用错Map
类型,否则会破坏业务排序。Summary of your change
修复 bug #3293 和 bug #3328
实现思路是:
Filter
时 和 无Filter
的表现一致,最好的方式是两边共用相同的isWriteAsString
判断逻辑 和writeName
写入处理代码。writeName
的代码是分散在多个类的多个方法里面,且夹杂其他与 name 无关的业务逻辑,无法统一抽取封装,难以实现全部共用。null
、String
、Integer
、Long
等常见类型,可直接复用。WriteNonStringKeyAsString
或BrowserCompatible
等 Feature,且属于内置简单类型的,直接key.toString()
。JSON.toJSONString()
,如果返回的字符串两侧带了引号的,就会被手动去掉。实际上自定义类型序列化的结果无非就是三种:数组[]
、对象{}
和 字符串""
,目前主要还是Enum
和 时间类型,对应的JSON输出会被额外加引号。这只是第一版的实现方案,先确保加了
WriteNonStringKeyAsString
或BrowserCompatible
Feature 的,还是可以正常使用。毕竟,最常见的一般就只有 字符串、整型、枚举。只要恢复对这些类型的支持,就满足了绝大多数场景下的需求。
至于上面第5步,可能会多耗费一点性能。但和之前相比,也只有在两侧多了引号时才会增加性能开销,并且这种场景在前端输出时非常少见。
此外,我也已经完成了第二版实现,着重优化第5点的性能,能够实现无需调用
JSON.toJSONString()
和 去除引号 的额外开销。第二版也已经通过了单元测试。不过有一个细节我还要再斟酌一下,需要覆盖更多场景,所以暂时先提交第一版。
Please indicate you've done the following: