最近寫的一個東西需要對json字符串進行格式化然后顯示在網頁上面。
我就想去網上找找有沒有這樣的api可以直接調用。百度 json api ,搜索結果都是那種只能在網頁上進行校驗的工具,沒有api。
那只有自己去實現一個json 格式化工具。
仔細分析,實現起來並不是很困難,至少思路很清晰。
需要解決的幾個問題:
- 對json的校驗:主要是符號的匹配;
- 格式化預處理:去除鍵值對之間的空白字符;
- 格式化:主要是縮進的問題,要符合json通常展示的格式。
解決的辦法:
- 針對A問題:
可以采用棧去匹配符號,大括號、中括號、雙引號等。
- 針對B問題:
可以用fastjson的JSONObject.toString()方法實現,自動去除鍵值對之間的空白字符。
- 針對C問題:
在需要換行的地方追加\n,縮進的地方追加\t。通過控制追加的\t的個數從而控制縮進量。如:
"{"、"[" 后面追加 \n,並且\t在上次數量上加一;
"}"、"]" 追加\n,\t在上次的數量上減一;
",": 追加\n和上次相同數量的\t。
具體實現:
1 package com.lm.algorithm.json; 2 3 import com.alibaba.fastjson.JSONException; 4 import com.alibaba.fastjson.JSONObject; 5 6 /** 7 * Created by LiuMian on 2015/12/17. 8 * 將json字符串添加 換行符和制表符使其能夠直接在網頁上按照通常的json格式顯示 9 */ 10 public class JSONFormat { 11 12 private String src; 13 private int TABLength = 0; 14 15 private final String BRACKET_LEFT = "["; 16 private final String BRACKET_RIGHT = "]"; 17 private final String BRACE_LEFT = "{"; 18 private final String BRACE_RIGHT = "}"; 19 private final String COMMA = ","; 20 private final String LINE_BREAK = "\n"; 21 private final String TAB = "\t"; 22 23 24 public JSONFormat(String src){ 25 this.src = src; 26 } 27 28 public String format() throws JSONException{ 29 try{ 30 JSONObject json = JSONObject.parseObject(src); 31 }catch (JSONException e){ 32 //對json進行簡單的校驗,如果不符合格式那么jsonobject在解析的時候會報錯 33 throw e; 34 } 35 return format(src); 36 } 37 38 private String format(String src) { 39 StringBuffer result = new StringBuffer(); 40 char[] srcArray = src.toCharArray(); 41 for (int index = 0; index < src.length(); index++) { 42 result.append(srcArray[index]); 43 44 if (BRACE_LEFT.equals(String.valueOf(srcArray[index]))) //{ 45 result.append(appendLINE_BREAKAndTAB(++TABLength)); 46 47 if (BRACE_RIGHT.equals(String.valueOf(srcArray[index]))) //} 48 result.insert(result.length() - 1, appendLINE_BREAKAndTAB(--TABLength)); 49 50 if (BRACKET_LEFT.equals(String.valueOf(srcArray[index]))) //[ 51 result.append(appendLINE_BREAKAndTAB(++TABLength)); 52 53 if (BRACKET_RIGHT.equals(String.valueOf(srcArray[index]))) //] 54 result.insert(result.length() - 1, appendLINE_BREAKAndTAB(--TABLength)); 55 56 if (COMMA.equals(String.valueOf(srcArray[index]))) //, 57 result.append(appendLINE_BREAKAndTAB(TABLength)); 58 } 59 return result.toString(); 60 } 61 62 //追加換行符和 確定長度的制表符 63 private String appendLINE_BREAKAndTAB(int TABTimes) { 64 StringBuffer temp = new StringBuffer(); 65 temp.append(appendLINE_BREAK()); 66 temp.append(appendTAB(TABTimes)); 67 return temp.toString(); 68 } 69 70 private String appendLINE_BREAK() { 71 return LINE_BREAK; 72 } 73 74 private String appendTAB(int TABTimes) { 75 StringBuffer temp = new StringBuffer(); 76 for (int i = 0; i < TABTimes; i++) { 77 temp.append(TAB); 78 } 79 return temp.toString(); 80 } 81 82 public static void main(String[] args) { 83 String toFormat = "{\"status\": \"3\",\"message\": \"\",\"errCode\": \"0\",\"data\": [{\"time\": \"2013-02-26 16:47\",\"context\": \"客戶 同事收發家人 已簽收 派件員 張xx\"},{\"time\": \"2013-02-26 07:33\",\"context\": \"吉林省xx市xx公司 的派件員 張金達 派件中 派件員電話15xxx73xx87\"},{\"time\": \"2013-02-26 06:02\",\"context\": \"xx省xx市xx公司 已收入\"},{\"time\": \"2013-02-25 15:42\",\"context\": \"xx省xx轉運中心公司已發出\"},{\"time\":\"2013-02-25 14:59\",\"context\":\"xx省xx轉運中心公司已拆包\"},{\"time\": \"2013-02-24 18:11\",\"context\":\"遼寧省大連市中山區四部公司 已收件\"},{\"time\": \"2013-02-24 17:59\",\"context\":\"遼寧省大連市公司 已收入\"},{\"time\":\"2013-02-23 17:10\",\"context\":\"遼寧省大連市中山區xxxx公司 的收件員 王xx 已收件\" }],\"html\":\"\",\"mailNo\":\"71xxxxx624\",\"expTextName\":\"圓通快遞\",\"expSpellName\":\"yuantong\",\"update\":\"1375155719\",\"cache\":\"33196560\",\"ord\":\"DESC\"}"; 84 JSONFormat jsonFormat = new JSONFormat(toFormat); 85 System.out.println(jsonFormat.format()); 86 } 87 88 }
效果圖:
1 { 2 "status": "3", 3 "message": "", 4 "errCode": "0", 5 "data": [ 6 { 7 "time": "2013-02-26 16:47", 8 "context": "客戶 同事收發家人 已簽收 派件員 張xx" 9 }, 10 { 11 "time": "2013-02-26 07:33", 12 "context": "吉林省xx市xx公司 的派件員 張金達 派件中 派件員電話15xxx73xx87" 13 }, 14 { 15 "time": "2013-02-26 06:02", 16 "context": "xx省xx市xx公司 已收入" 17 }, 18 { 19 "time": "2013-02-25 15:42", 20 "context": "xx省xx轉運中心公司已發出" 21 }, 22 { 23 "time":"2013-02-25 14:59", 24 "context":"xx省xx轉運中心公司已拆包" 25 }, 26 { 27 "time": "2013-02-24 18:11", 28 "context":"遼寧省大連市中山區四部公司 已收件" 29 }, 30 { 31 "time": "2013-02-24 17:59", 32 "context":"遼寧省大連市公司 已收入" 33 }, 34 { 35 "time":"2013-02-23 17:10", 36 "context":"遼寧省大連市中山區xxxx公司 的收件員 王xx 已收件" 37 } 38 ], 39 "html":"", 40 "mailNo":"71xxxxx624", 41 "expTextName":"圓通快遞", 42 "expSpellName":"yuantong", 43 "update":"1375155719", 44 "cache":"33196560", 45 "ord":"DESC" 46 }
如果把這個放在web項目里面,然后別人就可以根據api協議以Get或者Post請求的方式來調用你的json格式化工具啦~~
不足:沒有對A問題進行實現,只是簡單的借用了fastjson的JSONObject.parseObject()方法。
這樣做雖然簡單,但是有明顯的缺陷:如果某一行不符合json格式要求你只能通過拋出一個異常的方式告知調用者,而不能准確的定位在某一行。
這個格式化工具最難的地方也是在這里,需要用棧來匹配符號,這就要求對json有比較清晰地了解。
大家有好的思路或者想法,歡迎一起交流~
