最近和一個第三方的系統對接,需要把他們的請求參數保存下來,但是那一長串的json不好讀,於是想格式化一下,這種工具有很多,但我想自己弄個來玩下。
剛開始的實現用了很多判斷,邏輯很繞。后來想起之前讀過一個模板引擎的源碼,里面用了狀態圖,於是我也嘗試用了下。
public class Main {
private static String NEW_LINE = "\r\n";
public static void main(String[] args) {
String json = "[{\"name\": \"wen\",\"age\": 12,\"flag\": true,\"job\": [{\"name\":\"java\"},{\"name\": \"c++\"}]},{\"name\": \"yun\",\"age\": 13,\"flag\": false}]";
System.out.println(format(json));
}
private static String format(String json) {
// 去除原來的格式
json = json.replace("\n", "").replace("\r", "").replace("\t", "");
StringBuilder sb = new StringBuilder();
int prevStatus = 0;// 上一狀態
int level = 0;// 縮進層級
for (char c : json.toCharArray()) {
int oper = getOperation(prevStatus, c);
switch (oper) {
case 1:
sb.append(NEW_LINE).append(getTab(level));
break;
case 2:
level++;
sb.append(NEW_LINE).append(getTab(level));
break;
case 3:
level--;
sb.append(NEW_LINE).append(getTab(level));
break;
case 4:
sb.append(' ');
break;
}
sb.append(c);
prevStatus = getStatus(c);
}
return sb.toString();
}
// 返回:0直接輸出,1換行,2增加縮進並換行,3減少縮進並換行,4前面加空格
private static int[][] statusArr = new int[][] {
{0, 0, 0, 0, 0, 3}, // 普通字符
{1, 2, 2, 0, 0, 0}, // {[
{2, 0, 4, 0, 0, 0}, // :
{3, 1, 4, 0, 0, 0}, // ,
{4, 0, 0, 0, 0, 3},};// }]
// 根據前一狀態和當前字符決定操作
private static int getOperation(int status, char c) {
return statusArr[status][getStatus(c) + 1];
}
// 字符轉換成對應狀態
private static int getStatus(char c) {
int status = 0;
switch (c) {
case '{':
case '[':
status = 1;
break;
case ':':
status = 2;
break;
case ',':
status = 3;
break;
case '}':
case ']':
status = 4;
break;
}
return status;
}
// 縮進
private static String getTab(int level) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < level; i++) {
sb.append(" ");
}
return sb.toString();
}
}
執行結果
[
{
"name": "wen",
"age": 12,
"flag": true,
"job": [
{
"name":"java"
}, {
"name": "c++"
}
]
}, {
"name": "yun",
"age": 13,
"flag": false
}
]
