问题描述 fastjson通过代码指定全局序列化返回时间格式,导致使用JSONField注解标注属性的特殊日期返回格式失效 使用版本 应用名称版本 springboot2.0.0.RELEASEfastjson1.2.83 全局设置代码 pub
问题描述
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); } }