一、問題描述
近期項(xiàng)目開發(fā)過程中,項(xiàng)目使用的是前后端分離架構(gòu),前端使用ANT DESIGN VUE,后端采用SpringBoot+Mybatis,數(shù)據(jù)庫使用PG。如果前端定義的VUE變量為空串,后端用實(shí)體接收后,保存到數(shù)據(jù)庫中該變量的字段會(huì)為空串,而不是NULL,從而出現(xiàn)后端服務(wù)在發(fā)起數(shù)據(jù)庫查詢時(shí),用IS NULL條件無法過濾出來字段為空的數(shù)據(jù)記錄問題。
二、解決思路
針對(duì)上述提到的問題,有兩種方案:
1、修改前端上送的所有頁面代碼,初始化變量時(shí),將空串‘’全部替換成NULL
–修改的地方比較多,并且不能確保服務(wù)接口類的請(qǐng)求有出現(xiàn)空串,不建議使用
2、修改后端代碼,在應(yīng)用請(qǐng)求接收變量映射(將JSON字符串轉(zhuǎn)成JAVA實(shí)體)處,統(tǒng)一將空串‘’替換成NULL
–修改地方比較少,可做到統(tǒng)一控制,兼容前端界面和接口請(qǐng)求,建議使用該方案
現(xiàn)行項(xiàng)目使用的SpringBoot框架,針對(duì)JSON的解析,將Jakson解析統(tǒng)一替換成FastJson,(解決jackson 解析的字段中有單個(gè)字母作為駝峰單詞的, 單個(gè)字母后面的大寫字母會(huì)默認(rèn)取小寫的, 而不是原樣取值的問題如”wWorkDays”字段,使用jackson解析成JSON字符串時(shí),會(huì)變成wworkDays,以致原樣字段無法正確取值和傳送),因此要實(shí)現(xiàn)對(duì)字符串變量做個(gè)性化處理,因此考慮在Fastjson的的反序列化邏輯中添加此處理邏輯,方案如下:
fastJsonConfig.getParserConfig().putDeserializer(String.class, new ObjectDeserializer() {@Overridepublic T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {if (String.class.equals(type)) {String fieldValue = (String) parser.parse(fieldName);if (StrUtil.isBlank(fieldValue)) {fieldValue = null;}return (T) fieldValue;}return (T) parser.parse(fieldName);}
最終代碼如下:
/** * 將SpringBoot的Jakson解析統(tǒng)一替換成FastJson * 以解決jackson 解析的字段中有單個(gè)字母作為駝峰單詞的, 單個(gè)字母后面的大寫字母會(huì)默認(rèn)取小寫的, 而不是原樣取值的問題 * 如”wWorkDays”字段,使用jackson解析成JSON字符串時(shí),會(huì)變成wworkDays,以致原樣字段無法正確取值和傳送 * 使用FastJson可解決該問題 * * @return */@Beanpublic HttpMessageConverters fastJsonHttpMessageConverters() {FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();fastJsonHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());fastJsonHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);FastJsonConfig fastJsonConfig = new FastJsonConfig();fastJsonConfig.setDateFormat(“yyyy-MM-dd’T’HH:mm:ss.SSSXXX”);//全局轉(zhuǎn)化成帶時(shí)區(qū)的時(shí)間,例如,2021-09-28T09:28:05.000+08:00fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect, //禁用循環(huán)引用SerializerFeature.IgnoreNonFieldGetter,//忽略NULL字段SerializerFeature.WriteDateUseDateFormat//使用統(tǒng)一的時(shí)間格式);// 對(duì)String變量反序列化進(jìn)行定制處理,如果字符串為空串,則轉(zhuǎn)為NULL// 注:由于前端定義的字符為空串,發(fā)送到后臺(tái)保存到數(shù)據(jù)庫會(huì)保存為空串,在PG數(shù)據(jù)庫和MYSQL數(shù)據(jù)庫查詢時(shí)用,isNULL無法過濾出來記錄fastJsonConfig.getParserConfig().putDeserializer(String.class, new ObjectDeserializer() {@Overridepublic T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {if (String.class.equals(type)) {String fieldValue = (String) parser.parse(fieldName);if (StrUtil.isBlank(fieldValue)) {fieldValue = null;}return (T) fieldValue;}return (T) parser.parse(fieldName);}@Overridepublic int getFastMatchToken() {return 0;}});fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);return new HttpMessageConverters(new StringHttpMessageConverter(StandardCharsets.UTF_8), fastJsonHttpMessageConverter);}/** * 支持的文檔類型 * * @return */private List getSupportedMediaTypes() {List supportedMediaTypes = new ArrayList();supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);supportedMediaTypes.add(MediaType.APPLICATION_JSON);return supportedMediaTypes;}
三、問題總結(jié)
我們開發(fā)人員在碰到問題時(shí)頭腦應(yīng)該保持冷靜,從了解原理出發(fā),只要解決思路對(duì),總會(huì)找到正確的解決之道。