fastjson2 icon indicating copy to clipboard operation
fastjson2 copied to clipboard

fastjson2兼容包作为springboot默认序列化组件,无法默认序列化Date为时间戳

Open feistel opened this issue 1 year ago • 4 comments

问题描述

简要描述您碰到的问题。 用的fastjson2 兼容包,针对Date类型,直接通过JSON.toJSONString就是默认序列化为时间戳的。

但是通过WebMvcConfigurer 替换springboot默认的jaskson序列化方式的时候,就不生效,直接序列化为yyyy-MM-dd HH:mm:ss 这种形式了 即便在FastJsonConfig设置dateformat= "millis" 也不会生效,请问这种问题该怎么解决呀

环境信息

请填写以下信息:

  • JDK信息: 1.8.0
  • 版本信息:fastjson 2.0.52

重现步骤

import java.nio.charset.StandardCharsets;
import java.util.List;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MessageConverterWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        // 定义配置信息
        FastJsonConfig config = new FastJsonConfig();
        converter.setFastJsonConfig(config);
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        converters.add(0, converter);
    }
}

期待的正确结果

默认序列化为时间错类型(millis)

feistel avatar Aug 02 '24 04:08 feistel

@feistel Can you provide a complete testcase?

VictorZeng avatar Aug 09 '24 07:08 VictorZeng

@VictorZeng fastjson2的JSON.toJSONString,date序列为yyyy-MM-dd HH:mm:ss fastjson1.x的JSON.toJSONString,date序列为mill 下面是测试代码和截图:

  1. fastjson2的JSON
import com.alibaba.fastjson2.JSON;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;


@RequestMapping("/test")
@RestController
public class Issue2850 {
    static class TestData {
        public TestData() {
        }

        public TestData(Date showDate) {
            this.showDate = showDate;
        }

        private Date showDate;

        public Date getShowDate() {
            return showDate;
        }

        public void setShowDate(Date showDate) {
            this.showDate = showDate;
        }

        @Override
        public String toString() {
            return "TestData{" +
                    "showDate=" + showDate +
                    '}';
        }
    }

    @RequestMapping(path = "/issue2850/v1", produces = "application/json")
    public TestData issue2850V1() {
        return new TestData(new Date());
    }

    @RequestMapping(path = "/issue2850/v2", produces = "application/json")
    public String issue2850V2() {
        return JSON.toJSONString(new TestData(new Date()));
    }
}

image image

  1. fastjson1.的JSON
import com.alibaba.fastjson.JSON;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * @author: mek
 * Date: 2024/8/10
 * Time: 15:15
 * vx: 250023777
 * Description: Issue 2850
 * @version: 1.0
 */
@RequestMapping("/test")
@RestController
public class Issue2850 {
    static class TestData {
        public TestData() {
        }

        public TestData(Date showDate) {
            this.showDate = showDate;
        }

        private Date showDate;

        public Date getShowDate() {
            return showDate;
        }

        public void setShowDate(Date showDate) {
            this.showDate = showDate;
        }

        @Override
        public String toString() {
            return "TestData{" +
                    "showDate=" + showDate +
                    '}';
        }
    }

    @RequestMapping(path = "/issue2850/v1", produces = "application/json")
    public TestData issue2850V1() {
        return new TestData(new Date());
    }

    @RequestMapping(path = "/issue2850/v2", produces = "application/json")
    public String issue2850V2() {
        return JSON.toJSONString(new TestData(new Date()));
    }
}

image image

mek1986 avatar Aug 10 '24 08:08 mek1986

@VictorZeng fastjson2的JSON.toJSONString,date序列为yyyy-MM-dd HH:mm:ss fastjson1.x的JSON.toJSONString,date序列为mill 下面是测试代码和截图:

  1. fastjson2的JSON
import com.alibaba.fastjson2.JSON;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;


@RequestMapping("/test")
@RestController
public class Issue2850 {
    static class TestData {
        public TestData() {
        }

        public TestData(Date showDate) {
            this.showDate = showDate;
        }

        private Date showDate;

        public Date getShowDate() {
            return showDate;
        }

        public void setShowDate(Date showDate) {
            this.showDate = showDate;
        }

        @Override
        public String toString() {
            return "TestData{" +
                    "showDate=" + showDate +
                    '}';
        }
    }

    @RequestMapping(path = "/issue2850/v1", produces = "application/json")
    public TestData issue2850V1() {
        return new TestData(new Date());
    }

    @RequestMapping(path = "/issue2850/v2", produces = "application/json")
    public String issue2850V2() {
        return JSON.toJSONString(new TestData(new Date()));
    }
}

image image

  1. fastjson1.的JSON
import com.alibaba.fastjson.JSON;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * @author: mek
 * Date: 2024/8/10
 * Time: 15:15
 * vx: 250023777
 * Description: Issue 2850
 * @version: 1.0
 */
@RequestMapping("/test")
@RestController
public class Issue2850 {
    static class TestData {
        public TestData() {
        }

        public TestData(Date showDate) {
            this.showDate = showDate;
        }

        private Date showDate;

        public Date getShowDate() {
            return showDate;
        }

        public void setShowDate(Date showDate) {
            this.showDate = showDate;
        }

        @Override
        public String toString() {
            return "TestData{" +
                    "showDate=" + showDate +
                    '}';
        }
    }

    @RequestMapping(path = "/issue2850/v1", produces = "application/json")
    public TestData issue2850V1() {
        return new TestData(new Date());
    }

    @RequestMapping(path = "/issue2850/v2", produces = "application/json")
    public String issue2850V2() {
        return JSON.toJSONString(new TestData(new Date()));
    }
}

image image

fastjson配置就是用的提问者发的配置

mek1986 avatar Aug 10 '24 09:08 mek1986

貌似没有这个bug啊。我本地使用2.0.52兼容包进行测试:

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.52</version>
 </dependency>

并通过WebMvcConfigurer配置了FastJsonConfig,设置DateFormat("millis"),然后测试了下面三种情况都没有问题(2.0.57也没有这个问题):

    @RestController
    public static class TestController {
        @GetMapping(value = "/issue2850", produces = "application/json")
        public Date issue2850() {
//            return JSON.toJSONString(new Date());
//            return new TestData(new Date());
            return new Date();
        }
    }
    @Data
    @AllArgsConstructor
    public static class TestData{
        private Date date;
    }

然后试了一下,只有在使用非兼容版fastjson2替换jackson,并且在控制器方法return JSON.toJSONString(new Date())时才会触发提问者的情况,但是这种是合理的,因为在控制器方法return之前Date类型已经被转为yyyy-MM-dd HH:mm:ss字符串了,在响应时MVC的转换器读到只是一个字符串,无法转换成时间戳。这种算是重复序列化了,MvcConfig已经配置了就没必要在控制器再toJSON

jujn avatar Jun 02 '25 08:06 jujn

https://github.com/alibaba/fastjson2/releases/tag/2.0.58 问题已修复,请用新版本

wenshao avatar Jul 30 '25 05:07 wenshao