fastjson自定义ValueFilter后 丢失value为null的属性
背景:
使用List<Map<String, Object>> 接收 mybatisplus自定义sql查询所有数据,在JSON序列化时,日期时间变成了number类型,以及BigDecimal前端接收时,精度丢失
所以自定义了ValueFilter将BigDecimal转为字符串避免精度丢失,自定义方法将 TIMESTAMP(oracle.sql.TIMESTAMP)类型格式化为yyyy-MM-dd HH:mm:ss日期字符串
// 自定义 ValueFilter 来确保日期字符串不被重新解析为数值
ValueFilter dateFilter = new ValueFilter() {
@Override
public Object process(Object object, String name, Object value) {
if (value instanceof TIMESTAMP) {
return value;
}
if (name.equals("ID") && value instanceof Number) { // 避免精度丢失
return value.toString();
}
return value;
}
};
public static List<Map<String, Object>> formatTimestampsInList(List<Map<String, Object>> records) throws SQLException {
// 定义日期格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
for (Map<String, Object> record : records) {
// 处理TIMESTAMP类型数据
// 遍历记录中的所有键值对
for (String key : record.keySet()) {
Object value = record.get(key);
// 检查值是否为 Timestamp 类型
if (value instanceof TIMESTAMP) {
TIMESTAMP oracleTimestamp = (TIMESTAMP) value;
LocalDateTime localDateTime = oracleTimestamp.timestampValue().toLocalDateTime();
String formattedDate = localDateTime.format(formatter);
record.put(key, formattedDate);
}
}
}
// 返回修改后的页面对象
return records;
}
@Select("select * from ${tableName} ${condition} ")
List<Map<String, Object>> queryAllDataByTName(
@Param("tableName") String tableName,
@Param("condition") String condition
);
List<Map<String, Object>> res = mapper.queryAllDataByTName(tName , String.valueOf(setValues));
String json = JSON.toJSONString(formatTimestampsInList(res), dateFilter, SerializerFeature.WriteDateUseDateFormat);
JSONArray arrays = JSONObject.parseArray(json);
问题:
经过测试,当入参Object的value为null时,整个字段会丢失,PS:Null数据被FastJSON默认忽略了。
修复方法:
追加 SerializerFeature.WriteMapNullValue 即可
String json = JSON.toJSONString(formatTimestampsInList(res), dateFilter, SerializerFeature.WriteDateUseDateFormat, SerializerFeature.WriteMapNullValue);