首頁 > 軟體

fastjson全域性日期序列化設定導致JSONField失效問題解決方案

2023-01-04 14:00:22

問題描述

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日期序列化內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com