今天在改一個bug
情況:
在spring boot中寫了一個類Result ,用來統一封裝 各個API響應結果 , 其中重寫了toString()方法來返回 json字符串 。
在正常情況下,從其它API 返回給前端的結果都是json字符串,前端可以正確解析
但遇到一些異常的情況,返回給前端的結果卻是json對象數據,key少了雙引號,前端無法正確解析
從一開始調試到后面網上查找各種資料,想過有可能是注解、方法重寫、調用等方面出錯,但都難以找到根源
直到后面看到一篇文章說到write() 方法對結果的處理問題,才有所悟,並調試確定了根源
其他能夠正確返回json 字符串的,是因為 RestController 注解自動將對象轉成了json字符串
而 response.getWriter().write() 是直接將json對象寫進去,並沒有自動轉換成json字符串格式
1 private void responseResult(HttpServletResponse response, Result<?> result) { 2 response.setCharacterEncoding("UTF-8"); 3 response.setHeader("Content-Type", "application/json"); 4 response.setHeader("Access-Control-Allow-Credentials", "true"); 5 response.setHeader("Access-Control-Allow-Methods", "GET, POST"); 6 response.setHeader("Access-Control-Allow-Origin", "*"); 7 response.setHeader("Access-Control-Max-Age", "3600"); 8 // response.setHeader("Content-type", "application/json;charset=UTF-8"); 9 response.setStatus(HttpServletResponse.SC_OK); 10 response.setContentType("application/json;charset=UTF-8"); 11 // ServletOutputStream out = null; 12 PrintWriter writer=null; 13 try { 14 // JSON.toJSONString(result)要獲取完整的json字符串,每一個字段都要有set和get方法,不然會缺少某個字段 15 // response.getWriter().write(JSON.toJSONString(result)); 16 writer=response.getWriter(); 17 // writer.write(result.toString()); 18 writer.write(JSON.toJSONString(result)); 19 writer.flush(); 20 } catch (IOException ex) { 21 logger.error(ex.getMessage()); 22 }finally { 23 if(writer!=null) { 24 writer.close(); 25 } 26 } 27 }
而至於重寫的toString()方法為什么沒有直接返回json字符串
1 @Override 2 public String toString() { 3 Map<String, Object> resultMap=new ConcurrentHashMap<String, Object>(); 4 resultMap.put("code", code); 5 resultMap.put("result", result); 6 resultMap.put("msg", msg); 7 if(data!=null) { 8 resultMap.put("data", data); 9 }else { 10 resultMap.put("data", ""); 11 } 12 return JSON.toJSONString(resultMap, SerializerFeature.WRITE_MAP_NULL_FEATURES); 13 }
現在終於找到問題了
resultMap:{result=false, msg=訪問token無效, code=401, data=} JSON.toJSONString(resultMap):{"result":false,"msg":"訪問token無效","code":401,"data":""} JSON.toJSONString(resultMap, SerializerFeature.WRITE_MAP_NULL_FEATURES):{result:false,msg:"訪問token無效",code:401,data:""}
可以看到 JSON.toJSONString(resultMap, SerializerFeature.WRITE_MAP_NULL_FEATURES) 返回的字符串中,key 是沒有雙引號的
這個算是 com.alibaba.fastjson 的一個坑吧
參考:
Spring的ResponseBody和RestController注解返回的json數據不是json字符串,而是json對象... https://blog.csdn.net/weixin_33890526/article/details/87167889
Object與json字符串的相互轉換 https://blog.csdn.net/justry_deng/article/details/80780175
fastjson:SerializerFeature屬性使用 https://blog.csdn.net/zxl2016/article/details/80987414
共同學習,共同進步,若有補充,歡迎指出,謝謝!