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

[BUG] 添加 JSONWriter.Feature.WriteClassName 特性后,long 值序列化后会有 "L" 字符。(算问题?还是有什么开关,可以关掉?) #2967

Open
noear opened this issue Sep 17, 2024 · 5 comments
Labels
bug Something isn't working

Comments

@noear
Copy link
Contributor

noear commented Sep 17, 2024

复现代码:

public class TypeTest {
    @Test
    public void test() throws Throwable {
        Bean data = new Bean();
        data.value = 12L;

        String output = JSON.toJSONString(data, JSONWriter.Feature.WriteClassName);

        System.out.println(output); //{"@type":"features.type0.TypeTest$Bean","value":12L}
        assertEquals("{\"@type\":\"features.type0.TypeTest$Bean\",\"value\":12}", output);
    }

    public static class Bean {
        private Long value;

        public Long getValue() {
            return value;
        }
    }
}
@noear noear added the bug Something isn't working label Sep 17, 2024
@CodePlayer
Copy link
Contributor

这是特性,设计如此。

你设置了 WriteClassName,那么 Fastjson 就会将属性的类型信息序列化进去,这样反序列化时才会自动恢复为正确的类型。

附加一个 L 就是便于 Long 类型和 Integer 等其他整型进行区分,而且占用的额外存储空间也不大。
如果是自定义类型,则是添加一个 @type 属性,其值即为完整的类型名称,例如 package.to.ClassName

@noear
Copy link
Contributor Author

noear commented Sep 18, 2024

@CodePlayer 希望再来个特性,能控制它的关闭:)。。。有些场景下,需要与其它框架的互通性

@CodePlayer
Copy link
Contributor

@CodePlayer 希望再来个特性,能控制它的关闭:)。。。有些场景下,需要与其它框架的互通性

如果要与其他框架互通,那你就不应该使用 WriteClassName 这种序列化方式。
这不只是 Long 类型的 L 后缀问题,其他框架也不一定能支持 "@type" 这种自定义类型识别呀。

感觉你考虑的实现思路有些误入歧途。如果要实现不同序列化框架之间的互通:

  1. 最好都使用相同的组件,这样就没有实现上的差异
  2. 如果不能使用相同的组件,那么就使用与单一框架无关的协议来通信。如果两边对数据类型都是已知的,那在传输过程中就不必附加这种类型信息,你不需要设置 WriteClassName,直接传输 纯数据 JSON,接收方自行反序列化为已知的类型即可 。
  3. 如果数据类型对双方是不确定的,那么必须用一种两边都能识别的方式来传递数据类型信息。具体如何实现,得取决于你的实际情况。

@noear
Copy link
Contributor Author

noear commented Sep 22, 2024

@CodePlayer 非你所想。。。大多 json 框架,都有 WriteClassName 类似的特性,都可以有 @type 属性。

@CodePlayer
Copy link
Contributor

@CodePlayer 非你所想。。。大多 json 框架,都有 WriteClassName 类似的特性,都可以有 @type 属性。

你可以说说大多数JSON框架是哪些呢 ?
类似的特性肯定都有,但是并没有统一约定为 @type 这个Fastjson使用的的类型属性名称。

也就是 JSON框架 默认并不是互通的,本质上就是,如何保存序列化对象自身的类型信息,在 JSON 框架领域并没有一个统一的标准,不然大家都会遵循规范统一实现了。

当然,结合框架的自定义功能设置,我们还是可以将不同框架的 类型 属性名称 调整为相同的。
至于 L,你也可以设置 JSONWriter.Feature.WriteLongAsString 将 Long 值序列化为字符串。
最后,无论如何,其他 JSON框架 也要能够自定义,允许你将 L后缀 或 数值字符串 自定义反序列化为 Long 类型。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants