方法
Format
package util;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @decs: JSON格式化
* @date: 2018/6/22 13:05
* @version: v 1.0
*/
public class Format {
private static Pattern SPACE_PATTERN = Pattern.compile("\\s+");
public static String format(String json, int tab) {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setPrettyPrinting();
Gson gson = gsonBuilder.create();
JsonParser jsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(json);
String formattedJson = gson.toJson(jsonElement);
if (tab != 2 && tab > 0) {
// 改每行前导空格数
String[] lines = formattedJson.split("\n");
StringBuilder formatted4spacesJson = new StringBuilder();
StringBuilder sb = new StringBuilder();
for (String line : lines) {
Matcher matcher = SPACE_PATTERN.matcher(line);
if (matcher.find()) {
String spaces = matcher.group();
int length = spaces.length();
if (length % 2 == 0) {
int spaceLevel = length / 2;
int spaceAmount = spaceLevel * tab;
for (int i = 0; i < spaceAmount; i++) {
sb.append(' ');
}
sb.append(line.substring(length));
line = sb.toString();
formatted4spacesJson.append(line);
formatted4spacesJson.append("\n");
sb.setLength(0);
}
} else {
formatted4spacesJson.append(line);
formatted4spacesJson.append("\n");
}
}
return formatted4spacesJson.toString();
}
return formattedJson;
}
public static String format(String json) {
return format(json, 4);
}
}
JsonFormat
package util;
/**
* Created on 2018/6/21.
*
* @desc JSON格式化
*/
public class JsonFormat {
/**
* 格式化JSON字符串
*
* @param json 未格式化JSON字符串
* @return 格式化JSON字符串
*/
public static String formatJson(String json) {
StringBuilder result = new StringBuilder();
int length = json.length();
int number = 0;
char key;
// 遍历输入字符串
for (int i = 0; i < length; i++) {
// 一【当前字符】
key = json.charAt(i);
// 二【当前字符前是括号/花括号】
if ((key == '[') || (key == '{')) {
// (1)前仍有字符且“:”,打印换行缩进
if ((i - 1 > 0) && (json.charAt(i - 1) == ':')) {
result.append('\n');
result.append(indent(number));
}
// (2)打印当前字符
result.append(key);
// (3)前方括号/花括号则后换行
result.append('\n');
// (4)每现一次前方括号/花括号,缩进次数增一
number++;
result.append(indent(number));
// (5)下次循环
continue;
}
// 三【当前字符后方括号/花括号】
if ((key == ']') || (key == '}')) {
// (1)后方括号/花括号则前换行
result.append('\n');
// (2)每现一次后方括号/花括号,缩进次数减一
number--;
result.append(indent(number));
// (3)打印当前字符
result.append(key);
// (4)当前字符后还有字符且不为“,”
if (((i + 1) < length) && (json.charAt(i + 1) != ',')) {
result.append('\n');
}
// (5)下次循环
continue;
}
// 四【当前字符逗号,逗号后换行缩进,不改缩进次数】
if ((key == ',')) {
result.append(key);
result.append('\n');
result.append(indent(number));
continue;
}
// 五【打印当前字符】
result.append(key);
}
return result.toString();
}
/**
* 返指定次数的缩进字符串(每次缩三空格,即SPACE)
*
* @param number 缩进次数
* @return 指定缩进次数的字符串
*/
private static String indent(int number) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < number; i++) {
String space = " ";
result.append(space);
}
return result.toString();
}
}
JsonTool
package util;
import java.util.ArrayList;
/**
* Created on 2018/6/22.
*
* @desc JSON
*/
public class JsonTool {
/**
* prefix of ascii string of native character
*/
private static String PREFIX = "\\u";
/**
* Native to ascii string. It's same as execute native2ascii.exe.
*
* @param str native string
* @return ascii string
*/
public static String native2Ascii(String str) {
char[] chars = str.toCharArray();
StringBuilder sb = new StringBuilder();
for (char aChar : chars) {
sb.append(char2Ascii(aChar));
}
return sb.toString();
}
/**
* Native character to ascii string.
*
* @param c native character
* @return ascii string
*/
private static String char2Ascii(char c) {
if (c > 255) {
StringBuilder sb = new StringBuilder();
sb.append(PREFIX);
int code = (c >> 8);
String tmp = Integer.toHexString(code);
if (tmp.length() == 1) {
sb.append("0");
}
sb.append(tmp);
code = (c & 0xFF);
tmp = Integer.toHexString(code);
if (tmp.length() == 1) {
sb.append("0");
}
sb.append(tmp);
return sb.toString();
} else {
return Character.toString(c);
}
}
/**
* unicode编码转汉字(ASCII编码转16进制编码)
*
* @param unicodeStr unicode编码
* @return 汉字
*/
public static String ascii2Native(String unicodeStr) {
StringBuilder sb = new StringBuilder();
int begin = 0;
int index = unicodeStr.indexOf(PREFIX);
while (index != -1) {
sb.append(unicodeStr.substring(begin, index));
sb.append(ascii2Char(unicodeStr.substring(index, index + 6)));
begin = index + 6;
index = unicodeStr.indexOf(PREFIX, begin);
}
sb.append(unicodeStr.substring(begin));
return sb.toString();
}
/**
* ASCII编码转16进制编码
*
* @param asciiStr ASCII编码
* @return 16进制编码
*/
private static char ascii2Char(String asciiStr) {
if (asciiStr.length() != 6) {
throw new IllegalArgumentException("Ascii string of a native character must be 6 character.");
}
if (!"\\u".equals(asciiStr.substring(0, 2))) {
throw new IllegalArgumentException("Ascii string of a native character must start with \"\\u\".");
}
String tmp = asciiStr.substring(2, 4);
int code = Integer.parseInt(tmp, 16) << 8;
tmp = asciiStr.substring(4, 6);
code += Integer.parseInt(tmp, 16);
return (char) code;
}
/**
* JSON字符串格式化
*
* @param jsonString JSON字符串
* @param fillStringUnit 每层之前占位符(空格、制表符)
* @return 格式化后JSON字符串
*/
public static String formatJson(String jsonString, String fillStringUnit) {
// 数据null返空
if (jsonString == null || jsonString.trim().length() == 0) {
return null;
}
// 预读取(分行)
ArrayList<String> eachRowStringList = new ArrayList<>();
{
String jsonTemp = jsonString;
// 预读取
while (jsonTemp.length() > 0) {
// 每行串
String eachRowString = getEachRowOfJsonString(jsonTemp);
// 存此行字符到List
eachRowStringList.add(eachRowString.trim());
// 除此行字符及其前字符后剩字符(执行下次循环)
jsonTemp = jsonTemp.substring(eachRowString.length());
}
}
int fixedLength = 0;
for (int i = 0; i < eachRowStringList.size(); i++) {
String token = eachRowStringList.get(i);
int length = token.getBytes().length;
if (length > fixedLength && i < eachRowStringList.size() - 1 && ":".equals(eachRowStringList.get(i + 1))) {
fixedLength = length;
}
}
StringBuilder buf = new StringBuilder();
int count = 0;
for (int i = 0; i < eachRowStringList.size(); i++) {
String token = eachRowStringList.get(i);
if (",".equals(token)) {
buf.append(token);
doFill(buf, count, fillStringUnit);
continue;
}
if (":".equals(token)) {
buf.append(" ").append(token).append(" ");
continue;
}
if ("{".equals(token)) {
String nextToken = eachRowStringList.get(i + 1);
if ("}".equals(nextToken)) {
i++;
buf.append("{ }");
} else {
count++;
buf.append(token);
doFill(buf, count, fillStringUnit);
}
continue;
}
if ("}".equals(token)) {
count--;
doFill(buf, count, fillStringUnit);
buf.append(token);
continue;
}
if ("[".equals(token)) {
String nextToken = eachRowStringList.get(i + 1);
if ("]".equals(nextToken)) {
i++;
buf.append("[ ]");
} else {
count++;
buf.append(token);
doFill(buf, count, fillStringUnit);
}
continue;
}
if ("]".equals(token)) {
count--;
doFill(buf, count, fillStringUnit);
buf.append(token);
continue;
}
buf.append(token);
// 左对齐
if (i < eachRowStringList.size() - 1
&& ":".equals(eachRowStringList.get(i + 1))) {
int fillLength = fixedLength - token.getBytes().length;
if (fillLength > 0) {
for (int j = 0; j < fillLength; j++) {
buf.append(" ");
}
}
}
}
return buf.toString();
}
/**
* 每行串({ }、[ ]等结尾)
*
* @param jsonString JSON字符串
* @return 每行串
*/
private static String getEachRowOfJsonString(String jsonString) {
StringBuilder buf = new StringBuilder();
boolean isInYinHao = false;
while (jsonString.length() > 0) {
// 头字符
String firstString = jsonString.substring(0, 1);
// 头字符标点{ }、[ ]
boolean flag = !isInYinHao
&& (":".equals(firstString) || "{".equals(firstString)
|| "}".equals(firstString)
|| "[".equals(firstString)
|| "]".equals(firstString) || ",".equals(firstString));
if (flag) {
// 且此行无数据则入此行
if (buf.toString().trim().length() == 0) {
buf.append(firstString);
}
break;
}
// 头字符外字符
jsonString = jsonString.substring(1);
// 汉字字符
if ("\\".equals(firstString)) {
buf.append(firstString);
buf.append(jsonString.substring(0, 1));
jsonString = jsonString.substring(1);
continue;
}
// 引号
if ("\"".equals(firstString)) {
buf.append(firstString);
if (isInYinHao) {
break;
} else {
isInYinHao = true;
continue;
}
}
buf.append(firstString);
}
return buf.toString();
}
private static void doFill(StringBuilder buf, int count, String fillStringUnit) {
buf.append("\n");
for (int i = 0; i < count; i++) {
buf.append(fillStringUnit);
}
}
}
大小
三法基同样数据生文件大小:
效果
Format
JsonFormat
JsonTool
结论
综合考虑JsonFormat较好。