某一天,我们系统服务的依赖方找到我们,问我们为什么时间类型的字段会有这种数据存在?导致他们解析的时候报错。
{"sloganEndtime": "20211-03-10 11:30:00"} // 字段类型 private Date sloganEndtime;
于是我们开始进行排查,最后发现数据源头来源于一个导入表格的功能,商家运营人员在导入数据的时候写错了,所以导致了非常离谱的问题。
利用原生JDK来转换时间 代码截图如下:会发现不会出现异常
我们换FastJson来尝试下,代码如下:发现会报错!
SkuMainBean mainBean = JSON.parseObject("{\"sloganEndTime\":\"20211-03-10 11:30:00\"}", SkuMainBean.class); System.out.println(mainBean); # 异常信息 Exception in thread "main" com.alibaba.fastjson.JSONException: For input string: "20211-03-10 11:30:00" at com.alibaba.fastjson.parser.DefaultJSONParser.parseObject(DefaultJSONPars er.java:627) at com.alibaba.fastjson.JSON.parseObject(JSON.java:361)
通过跟代码,我们发现FastJson有其自己的默认时间格式:
// com.alibaba.fastjson.JSON#DEFFAULT_DATE_FORMAT public static String DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
但是其使用判断逻辑是预先校验了FORMAT与入参的长度:
if (strVal.length() == parser.getDateFomartPattern().length()) { DateFormat dateFormat = parser.getDateFormat(); try { return (T) dateFormat.parse(strVal); } catch (ParseException e) { // skip } } // .................................... return (T) new java.util.Date(longVal);
1、主动增加格式化注解,尤其是需要转换未知的入参时,需要提前确定
@JSONField(format="yyyy-MM-dd HH:mm:ss") private Date sloganEndtime;
2、利用时间戳(Long)替换Date类型
3、自己的系统在进行数据传输时,保证数据的合理性,增加相关校验
PS:为什么不检测无注解直接转换失败?