Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue #3293 and issue #3328 #3384

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

CodePlayer
Copy link
Contributor

@CodePlayer CodePlayer commented Mar 12, 2025

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

实现思路是:

  1. 为了让有 Filter 时 和 无 Filter 的表现一致,最好的方式是两边共用相同的 isWriteAsString 判断逻辑 和 writeName 写入处理代码。
  2. 但是 writeName 的代码是分散在多个类的多个方法里面,且夹杂其他与 name 无关的业务逻辑,无法统一抽取封装,难以实现全部共用。
  3. 对于 nullStringIntegerLong 等常见类型,可直接复用。
  4. 设置了 WriteNonStringKeyAsStringBrowserCompatible 等 Feature,且属于内置简单类型的,直接 key.toString()
  5. 对于其他自定义类型(或没有设置上述 Feature 的),仍然调用之前的 JSON.toJSONString(),如果返回的字符串两侧带了引号的,就会被手动去掉。实际上自定义类型序列化的结果无非就是三种:数组[]、对象{} 和 字符串"",目前主要还是 Enum 和 时间类型,对应的JSON输出会被额外加引号。

这只是第一版的实现方案,先确保加了 WriteNonStringKeyAsStringBrowserCompatible Feature 的,还是可以正常使用
毕竟,最常见的一般就只有 字符串、整型、枚举。只要恢复对这些类型的支持,就满足了绝大多数场景下的需求。

至于上面第5步,可能会多耗费一点性能。但和之前相比,也只有在两侧多了引号时才会增加性能开销,并且这种场景在前端输出时非常少见。

此外,我也已经完成了第二版实现,着重优化第5点的性能,能够实现无需调用 JSON.toJSONString() 和 去除引号 的额外开销。
第二版也已经通过了单元测试。不过有一个细节我还要再斟酌一下,需要覆盖更多场景,所以暂时先提交第一版。

Please indicate you've done the following:

  • Made sure tests are passing and test coverage is added if needed.
  • Made sure commit message follow the rule of Conventional Commits specification.
  • Considered the docs impact and opened a new docs issue or PR with docs changes if needed.

@wenshao
Copy link
Member

wenshao commented Mar 13, 2025

两个issue的问题不是一个,请分开两个PR提交

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants