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] 使用JSONB解析带Jackson @JsonFormat 注解的Timestamp类会报错 #2332

Closed
Whitroom opened this issue Mar 18, 2024 · 5 comments
Closed
Labels
bug Something isn't working fixed
Milestone

Comments

@Whitroom
Copy link

问题描述

如标题

环境信息

  • OS信息: Windows 11 专业版 22631.3296
  • JDK信息: dragonwell jdk-17.0.9.0.10+9-GA
  • 版本信息:fastjson2 2.0.47

重现步骤

如何操作可以重现该问题:

  1. 创建maven项目,使用以下依赖:
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.47</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.16.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>
  1. 执行以下代码
public class Main {
    public static void main(String[] args) {
        DemoEntity entity = new DemoEntity();
        DemoEntity2 entity2 = new DemoEntity2();


        entity2.setNow(LocalDateTime.now());
        byte[] jsonString2 = JSONB.toBytes(entity2);
        // 不会报错
        System.out.println(JSONB.parseObject(jsonString2, DemoEntity2.class));


        entity.setNow(Timestamp.valueOf(LocalDateTime.now()));
        String jsonString3 = JSON.toJSONString(entity2);
        // 不会报错
        System.out.println(JSON.parseObject(jsonString3, DemoEntity2.class));


        byte[] jsonString = JSONB.toBytes(entity);
        // 会报错
        System.out.println(JSONB.parseObject(jsonString, DemoEntity.class));
    }

    @Data
    public static class DemoEntity {

        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Timestamp now;
    }

    @Data
    public static class DemoEntity2 {

        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private LocalDateTime now;
    }
}

期待的正确结果

对您期望发生的结果进行清晰简洁的描述。
如前两个用例,可以输出相应的值

相关日志输出

Exception in thread "main" com.alibaba.fastjson2.JSONException: readString not support type LOCAL_DATETIME -88, offset 6/19
at com.alibaba.fastjson2.JSONReaderJSONB.notSupportString(JSONReaderJSONB.java:2620)
at com.alibaba.fastjson2.JSONReaderJSONB.readStringTypeNotMatch(JSONReaderJSONB.java:3293)
at com.alibaba.fastjson2.JSONReaderJSONB.readStringNonAscii(JSONReaderJSONB.java:3029)
at com.alibaba.fastjson2.JSONReaderJSONB.readString(JSONReaderJSONB.java:3000)
at com.alibaba.fastjson2.util.JdbcSupport$TimestampReader.readObject(JdbcSupport.java:576)
at com.alibaba.fastjson2.util.JdbcSupport$TimestampReader.readJSONBObject(JdbcSupport.java:530)
at com.alibaba.fastjson2.reader.ORG_2_1_DemoEntity.readJSONBObject(Unknown Source)
at com.alibaba.fastjson2.JSONB.parseObject(JSONB.java:491)
at com.example.Main.main(Main.java:29)

@Whitroom Whitroom added the bug Something isn't working label Mar 18, 2024
@wenshao
Copy link
Member

wenshao commented Mar 18, 2024

https://oss.sonatype.org/content/repositories/snapshots/com/alibaba/fastjson2/fastjson2/2.0.48-SNAPSHOT/
问题已修复,请帮忙用2.0.48-SNAPSHOT版本帮忙验证,2.0.48版本预计在3月底前发布。

@wenshao wenshao added the fixed label Mar 18, 2024
@wenshao wenshao added this to the 2.0.48 milestone Mar 18, 2024
@Whitroom
Copy link
Author

非常感谢,虽然报错的问题已经解决了,但是JSON和JSONB序列化出来的时间有一些偏差,使用JSON会忽略毫秒,使用JSONB则不会,使用 Jackson @JsonFormat和 FastJSON2 @JsonField注解都是一样的,如下面的代码:

public class Main {
    public static void main(String[] args) {
        DemoEntity entity = new DemoEntity();
        entity.setNow(new Timestamp(System.currentTimeMillis()));

        DemoEntity2 entity2 = new DemoEntity2();
        entity2.setNow(new Timestamp(System.currentTimeMillis()));

        byte[] jsonString = JSONB.toBytes(entity);
        // 输出结果: Main.DemoEntity(now=2024-03-19 09:33:54.956)
        System.out.println(JSONB.parseObject(jsonString, DemoEntity.class));

        String jsonString1 = JSON.toJSONString(entity);
        // 输出结果: Main.DemoEntity(now=2024-03-19 09:33:54.0)
        System.out.println(JSON.parseObject(jsonString1, DemoEntity.class));

        byte[] jsonString2 = JSONB.toBytes(entity2);
        // 输出结果: Main.DemoEntity2(now=2024-03-19 09:33:54.957)
        System.out.println(JSONB.parseObject(jsonString2, DemoEntity2.class));

        String jsonString3 = JSON.toJSONString(entity2);
        // 输出结果: Main.DemoEntity2(now=2024-03-19 09:33:54.0)
        System.out.println(JSON.parseObject(jsonString3, DemoEntity2.class));
    }

    @Data
    public static class DemoEntity {

        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        private Timestamp now;
    }

    @Data
    public static class DemoEntity2 {

        @JSONField(format = "yyyy-MM-dd HH:mm:ss")
        private Timestamp now;
    }
}

这个是Bug还是Feature?

@wenshao
Copy link
Member

wenshao commented Mar 19, 2024

这个是BUG,已经修复精度问题,请帮忙更新快照验证。

@Whitroom
Copy link
Author

已经修复了,十分感谢,并且也可以通过 @JsonField@JsonFormat 注解进行格式化了😄

@wenshao
Copy link
Member

wenshao commented Mar 25, 2024

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

No branches or pull requests

2 participants