fastjson全局日期序列化设置导致JSONField失效问题解决方案

 更新时间:2023年01月02日 09:15:17   作者:code2roc  
这篇文章主要介绍了fastjson通过代码指定全局序列化返回时间格式,导致使用JSONField注解标注属性的特殊日期返回格式失效问题的解决方案

问题描述

fastjson通过代码指定全局序列化返回时间格式,导致使用JSONField注解标注属性的特殊日期返回格式失效

使用版本

应用名称版本
springboot2.0.0.RELEASE
fastjson1.2.83

全局设置代码

public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //1.需要定义一个convert转换消息的对象;
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        //2.添加fastJson的配置信息,比如:是否要格式化返回的json数据;
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        //全局指定了日期格式
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        //3处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        //4.在convert中添加配置信息.
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        //5.将convert添加到converters当中.
        converters.add(fastJsonHttpMessageConverter);
    }
}

属性设置代码

    @JSONField(format = "yyyy-MM-dd")
    private Date addDate;

返回结果

请求接口后addDate字段返回的格式为2022-12-17 13:26:45,仍然为全局日期格式,并不设置JSONField后期望的2022-12-17格式

解决方案

统一扫描

系统启动时扫描对应基类的子类,通过反射获取标注了JSONField注解的字段并获取对应的format值

public class FastJsonUtil {
    private static HashMap<String, String> dateMap = new HashMap();
    public static void scanDate2Json(Class runtimeClass, List<String> extraPackageNameList) {
        List<Class> filterClassList = new ArrayList<>();
        filterClassList.add(BaseSystemObject.class);
        List<Class<?>> scanClassList = new ArrayList<>();
        if (!runtimeClass.getPackage().getName().equals(Application.class.getPackage().getName())) {
            scanClassList.addAll(ScanUtil.getAllClassByPackageName(runtimeClass.getPackage(), filterClassList));
        }
        for (String packageName : extraPackageNameList) {
            scanClassList.addAll(ScanUtil.getAllClassByPackageName(packageName, filterClassList));
        }
        for (Class clazz : scanClassList) {
            List<Field> fs = Arrays.asList(clazz.getDeclaredFields());
            for (Field field : fs) {
                field.setAccessible(true);
                if (field.getType() == Date.class) {
                    JSONField jsonField = field.getAnnotation(JSONField.class);
                    if (jsonField != null && !StringUtil.isEmpty(jsonField.format())) {
                        dateMap.put(clazz.getName() + "|" + field.getName(), jsonField.format());
                    }
                }
            }
        }
    }
    public static boolean checkDate2Json(String key){
        return dateMap.containsKey(key);
    }
    public static String getDate2JsonFormat(String key){
        return dateMap.get(key);
    }
}

统一修改

实现fastjson的扩展过滤器ValueFilter进行序列化后的值修改,并注册到配置中去

public class FastJsonPropertyValueFilter implements ValueFilter {
    @Override
    public Object process(Object source, String name, Object value) {
        String key = source.getClass().getName() + "|" + name;
        if (value != null && FastJsonUtil.checkDate2Json(key)) {
            String format = FastJsonUtil.getDate2JsonFormat(key);
            DateFormat df = new SimpleDateFormat(format);
            return df.format(value);
        }
        return value;
    }
}
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //1.需要定义一个convert转换消息的对象;
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        //2.添加fastJson的配置信息,比如:是否要格式化返回的json数据;
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        //全局指定了日期格式
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        //指定json返回规则
        fastJsonConfig.setSerializeFilters(new FastJsonPropertyValueFilter());
        //3处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        //4.在convert中添加配置信息.
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
        //5.将convert添加到converters当中.
        converters.add(fastJsonHttpMessageConverter);
    }
}

到此这篇关于fastjson全局日期序列化设置导致JSONField失效问题解决方案的文章就介绍到这了,更多相关fastjson日期序列化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • File.createTempFile创建临时文件的示例详解

    File.createTempFile创建临时文件的示例详解

    这篇文章主要介绍了File.createTempFile创建临时文件的示例详解,在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。 如果感兴趣来了解一下
    2020-07-07
  • SpringBoot获取当前运行环境三种方式小结

    SpringBoot获取当前运行环境三种方式小结

    在使用SpringBoot过程中,我们只需要引入相关依赖,然后在main方法中调用SpringBootApplication.run(应用程序启动类.class)方法即可,那么SpringBoot是如何获取当前运行环境呢,接下来由小编给大家介绍一下SpringBoot获取当前运行环境三种方式,需要的朋友可以参考下
    2024-01-01
  • Java如何打印完整的堆栈信息

    Java如何打印完整的堆栈信息

    这篇文章主要为大家介绍了Java如何打印完整的堆栈信息示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • springboot中使用rabbitt的详细方法

    springboot中使用rabbitt的详细方法

    这篇文章主要介绍了springboot中使用rabbitt,通过本文学习让我们了解如何在Spring Boot中使用RabbitMQ,并使用不同的交换机和队列类型以及消息确认模式,需要的朋友可以参考下
    2023-05-05
  • java对象初始化顺序验证示例

    java对象初始化顺序验证示例

    以下这段小程序对调用对象构造函数时,父类构造函数、成员变量初始化函数,以及非静态初始化块调用顺序进行验证,不考虑静态成员及静态初始化块
    2014-02-02
  • Spring Boot 日志配置方法(超详细)

    Spring Boot 日志配置方法(超详细)

    默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台。下面通过本文给大家介绍Spring Boot 日志配置方法详解,感兴趣的朋友参考下吧
    2017-07-07
  • Java并发编程之ConcurrentLinkedQueue队列详情

    Java并发编程之ConcurrentLinkedQueue队列详情

    这篇文章主要介绍了Java并发编程之ConcurrentLinkedQueue队列详情,ConcurrentLinkedQueue 内部的队列使用单向链表方式实现,下文更多相关内容叙述需要的小伙伴可以参考一下
    2022-04-04
  • MybatisPlus字段自动填充失效,填充值为null的解决方案

    MybatisPlus字段自动填充失效,填充值为null的解决方案

    这篇文章主要介绍了MybatisPlus字段自动填充失效,填充值为null的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java实现弹窗效果的基本操作

    Java实现弹窗效果的基本操作

    这篇文章主要为大家详细介绍了Java实现弹窗效果的基本操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • 详解Spring Boot Mysql 版本驱动连接池方案选择

    详解Spring Boot Mysql 版本驱动连接池方案选择

    这篇文章主要介绍了详解Spring Boot Mysql 版本驱动连接池方案选择,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08

最新评论