fastjson全局日期序列化设置导致JSONField无效

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

问题描述

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

使用版本

应用名称 版本
springboot 2.0.0.RELEASE
fastjson 1.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);
    }

}
目录
相关文章
|
7月前
feign发起url请求日期序列化问题
feign发起url请求日期序列化问题
203 0
|
1月前
|
存储 JSON fastjson
再也不用心惊胆战地使用FastJSON了——序列化篇
本篇将主要介绍json序列化的详细流程。本文阅读的FastJSON源码版本为2.0.31。
217 13
|
3月前
|
JSON fastjson Java
niubility!即使JavaBean没有默认无参构造器,fastjson也可以反序列化。- - - - 阿里Fastjson反序列化源码分析
本文详细分析了 Fastjson 反序列化对象的源码(版本 fastjson-1.2.60),揭示了即使 JavaBean 沲有默认无参构造器,Fastjson 仍能正常反序列化的技术内幕。文章通过案例展示了 Fastjson 在不同构造器情况下的行为,并深入探讨了 `ParserConfig#getDeserializer` 方法的核心逻辑。此外,还介绍了 ASM 字节码技术的应用及其在反序列化过程中的角色。
98 10
|
JSON 前端开发 fastjson
fastjson全局序列化坑
fastjson全局序列化坑
108 0
|
前端开发 fastjson
mvc配置fastjson序列化枚举
mvc配置fastjson序列化枚举
127 0
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
1月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
1月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
2月前
|
存储 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第9天】在Java的世界里,对象序列化是连接数据持久化与网络通信的桥梁。本文将深入探讨Java对象序列化的机制、实践方法及反序列化过程,通过代码示例揭示其背后的原理。从基础概念到高级应用,我们将一步步揭开序列化技术的神秘面纱,让读者能够掌握这一强大工具,以应对数据存储和传输的挑战。
|
2月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第3天】在Java编程的世界里,对象序列化与反序列化是实现数据持久化和网络传输的关键技术。本文将深入探讨Java序列化的原理、应用场景以及如何通过代码示例实现对象的序列化与反序列化过程。从基础概念到实践操作,我们将一步步揭示这一技术的魅力所在。