import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* json格式化类
*/
public class JsonFormatterUtil {
//TEST
public static void main(String[] args) throws Exception {
String str = "{\"queryType\":\"lucene_timeseries\",\"dataSource\":\"druid-test\",\"granularity\":\"all\",\"context\":{\"timeout\":1800,\"useOffheap\":true,\"groupByStrategy\":\"v2\"},\"aggregations\":[{\"type\":\"lucene_hyperUnique\",\"name\":\"ageCount\",\"fieldName\":\"age\"}],\"intervals\":\"1000/3000\"}";
//JSON格式化 1,@link {http://www.bejson.com/}
str = toFormat(str,true,true);
System.out.println(str);
}
/**
* TODO json格式化方法 1
* 对json字符串进行格式化,
* 格式化核心逻辑来源于JSON格式化 @link {http://www.bejson.com/}
* @param content 要格式化的json字符串
* @param indent 是否进行缩进(false时压缩为一行)
* @param colonWithSpace key冒号后是否加入空格
* @return
*/
public static String toFormat(String content, boolean indent, boolean colonWithSpace) {
if (content == null) return null;
StringBuilder sb = new StringBuilder();
int count = 0;
boolean inString = false;
String tab = "\t";
for (int i = 0; i < content.length(); i ++) {
char ch = content.charAt(i);
switch (ch) {
case '{':
case '[':
sb.append(ch);
if (!inString) {
if (indent) {
sb.append("\n");
count ++;
for (int j = 0; j < count; j ++) {
sb.append(tab);
}
}
}
break;
case '\uFEFF': //非法字符
if (inString) sb.append(ch);
break;
case '}':
case ']':
if (!inString) {
if (indent) {
count --;
sb.append("\n");
for (int j = 0; j < count; j ++) {
sb.append(tab);
}
}
sb.append(ch);
} else {
sb.append(ch);
}
break;
case ',':
sb.append(ch);
if (!inString) {
if (indent) {
sb.append("\n");
for (int j = 0; j < count; j ++) {
sb.append(tab);
}
} else {
if (colonWithSpace) {
sb.append(' ');
}
}
}
break;
case ':':
sb.append(ch);
if (!inString) {
if (colonWithSpace) { //key名称冒号后加空格
sb.append(' ');
}
}
break;
case ' ':
case '\n':
case '\t':
if (inString) {
sb.append(ch);
}
break;
case '"':
if (i > 0 && content.charAt(i - 1) != '\\') {
inString = !inString;
}
sb.append(ch);
break;
default:
sb.append(ch);
break;
}
}
return sb.toString();
}
/**
* TODO json格式化方法 2
* JSON默认格式化,换行自动缩进两个字符
*/
public static String format(String jsonStr){
try {
ByteArrayInputStream in = new ByteArrayInputStream(jsonStr.getBytes());
ByteArrayOutputStream out = new ByteArrayOutputStream();
char ch;
int read;
int space=0;
while((read = in.read()) > 0){
ch = (char)read;
switch (ch){
case '{': {
space = outputAndRightMove(space, ch, out);
break;
}
case '[': {
out.write(ch);
space += 2;
break;
}
case '}': {
space = outputAndLeftMove(space, ch, out);
break;
}
case ']': {
space = outputAndLeftMove(space, ch, out);
break;
}
case ',': {
out.write(ch);
outputNewline(out);
out.write(getBlankingStringBytes(space));
break;
}
default: {
out.write(ch);
break;
}
}
}
return out.toString();
} catch (IOException e){
e.printStackTrace();
}
return null;
}
private static int outputAndRightMove(int space, char ch, ByteArrayOutputStream out) throws IOException {
//换行
outputNewline(out);
//向右缩进
out.write(getBlankingStringBytes(space));
out.write(ch);
outputNewline(out);
space += 2;
//再向右缩进多两个字符
out.write(getBlankingStringBytes(space));
return space;
}
private static int outputAndLeftMove(int space, char ch, ByteArrayOutputStream out) throws IOException{
outputNewline(out);
space -= 2;
out.write(getBlankingStringBytes(space));
out.write(ch);
return space;
}
private static byte[] getBlankingStringBytes(int space){
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < space; i++) {
sb.append(" ");
}
return sb.toString().getBytes();
}
private static void outputNewline(ByteArrayOutputStream out){
out.write('\n');
}
/**
* TODO json格式化方法 3
* json字符串的格式化
* @param jsonString Json字符数据
* @param fillStringUnit 每一层之前的占位符号比如空格 制表符
* @return String
*/
public static String formatJson(String jsonString, String fillStringUnit) {
// 数据为null,则返回空数据
if (jsonString == null || jsonString.trim().length() == 0) {
return null;
}
// 预读取(分行)
ArrayList<String> eachRowStringList = new ArrayList<String>();
{
String jsonTemp = jsonString;
// 预读取
while (jsonTemp.length() > 0) {
// 获取每一行的串
String eachRowString = getEachRowOfJsonString(jsonTemp);
// 将此行字符串存入List当中
eachRowStringList.add(eachRowString.trim());
// 除去此行字符及其之前字符串后,剩余的字符串(去执行下一次循环)
jsonTemp = jsonTemp.substring(eachRowString.length());
}
}
int fixedLenth = 0;
for (int i = 0; i < eachRowStringList.size(); i++) {
String token = eachRowStringList.get(i);
int length = token.getBytes().length;
if (length > fixedLenth && i < eachRowStringList.size() - 1
&& eachRowStringList.get(i + 1).equals(":")) {
fixedLenth = length;
}
}
StringBuilder buf = new StringBuilder();
int count = 0;
for (int i = 0; i < eachRowStringList.size(); i++) {
String token = eachRowStringList.get(i);
if (token.equals(",")) {
buf.append(token);
doFill(buf, count, fillStringUnit);
continue;
}
if (token.equals(":")) {
buf.append(" ").append(token).append(" ");
continue;
}
if (token.equals("{")) {
String nextToken = eachRowStringList.get(i + 1);
if (nextToken.equals("}")) {
i++;
buf.append("{ }");
} else {
count++;
buf.append(token);
doFill(buf, count, fillStringUnit);
}
continue;
}
if (token.equals("}")) {
count--;
doFill(buf, count, fillStringUnit);
buf.append(token);
continue;
}
if (token.equals("[")) {
String nextToken = eachRowStringList.get(i + 1);
if (nextToken.equals("]")) {
i++;
buf.append("[ ]");
} else {
count++;
buf.append(token);
doFill(buf, count, fillStringUnit);
}
continue;
}
if (token.equals("]")) {
count--;
doFill(buf, count, fillStringUnit);
buf.append(token);
continue;
}
buf.append(token);
// 左对齐
if (i < eachRowStringList.size() - 1
&& eachRowStringList.get(i + 1).equals(":")) {
int fillLength = fixedLenth - token.getBytes().length;
if (fillLength > 0) {
for (int j = 0; j < fillLength; j++) {
buf.append(" ");
}
}
}
}
return buf.toString();
}
//获取每一行的串, { } [ ]等结尾的串
private static String getEachRowOfJsonString(String jsonString) {
StringBuilder buf = new StringBuilder();
boolean isInYinHao = false;
while (jsonString.length() > 0) {
// 获取json串的第一个字符
String firstString = jsonString.substring(0, 1);
// 如果第一个字符串是标点符号: { } [ ] ,
if (!isInYinHao
&& (firstString.equals(":") || firstString.equals("{")
|| firstString.equals("}")
|| firstString.equals("[")
|| firstString.equals("]") || firstString
.equals(","))) {
// 并且此行没有数据,加入到此行当中
if (buf.toString().trim().length() == 0) {
buf.append(firstString);
}
break;
}
// 除第一个字符之外的其他字符
jsonString = jsonString.substring(1);
// 如果是汉字字符
if (firstString.equals("\\")) {
buf.append(firstString);
buf.append(jsonString.substring(0, 1));
jsonString = jsonString.substring(1);
continue;
}
// 如果是引号
if (firstString.equals("\"")) {
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);
}
}
/**
*TODO 将实体POJO转化为JSON字符串,并格式化
*/
public static String objToJsonStr(StringBuffer sb, Object object){
String str = "";
try {
str = objToJsonPrecess(sb,object); //异常的json ——> ",}"
str = str.replace(",}","}"); //正常的json ——> "}"
str = toFormat(str,true,true); //json格式化
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
// Object转化为JsonStr的处理过程
private static String objToJsonPrecess(StringBuffer sb ,Object obj) throws Exception {
Class<?> c = obj.getClass();
Field fields[] = c.getDeclaredFields();
sb.append("{");
try {
for(int i=0; i<fields.length; i++){
Field curField = fields[i];
Class<?> curFieType = curField.getType();
//属性可访问
curField.setAccessible(true);
//属性名称
String name = curField.getName();
//Java本身的类型
if(isJavaClass(curFieType)){
//List
if(curFieType.toString().endsWith("List")){
getListEle(sb, obj, curField, name, curFieType);
}
//非List
else{
//Integer
if(curFieType.toString().endsWith("Integer")) {
if(curField.get(obj) == null){
//属性值为空,给默认值
sb.append("\""+name+"\":"+0+",");
}else{
sb.append("\""+name+"\":"+curField.get(obj)+",");
}
}
//Double
else if(curFieType.toString().endsWith("Double")){
if(curField.get(obj) == null){
//属性值为空,给默认值
sb.append("\""+name+"\":"+0D+",");
}else{
sb.append("\""+name+"\":"+curField.get(obj)+",");
}
}
//Boolean
else if(curFieType.toString().endsWith("Boolean")){
if(curField.get(obj) == null){
//属性值为空,给默认值
sb.append("\""+name+"\":"+Boolean.FALSE+",");
}else{
sb.append("\""+name+"\":"+curField.get(obj)+",");
}
}
//Date
else if(curFieType.toString().endsWith("Date")){
if(curField.get(obj) == null){
//属性值为空,给默认值
sb.append("\""+name+"\":"+"\""+"2000-01-01 00:00:00"+"\",");
}else{
sb.append("\""+name+"\":"+"\""+dateToString((Date) curField.get(obj),new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))+"\",");
}
}
//String
else if(curFieType.toString().endsWith("String")){
if(curField.get(obj) == null){
//属性值为空,给默认值
sb.append("\""+name+"\":"+"\""+""+"\",");
}else{
sb.append("\""+name+"\":"+"\""+curField.get(obj)+"\",");
}
}else{
throw new Exception("未知的数据类型");
}
}
}
//非Java本身的类型
else{
//用户自定义的实体类类型
getObjectEle(sb, obj, curField, name);
}
}
} catch (Exception e) {
throw new Exception(e.getMessage());
}
sb.append("}");
return sb.toString();
}
// 获取用户自定义的实体类类型元素,转json
private static void getObjectEle(StringBuffer sb, Object obj, Field curField, String name) throws Exception {
// 得到泛型里的class类型对象
//Type genericType = curField.getGenericType();
//Class<?> actualTypeArgument = Class.forName(genericType.getTypeName());
Class<?> actualTypeArgument = curField.getType();
Object actualType = actualTypeArgument.newInstance();
//....actualType字段处理
curField.set(obj, actualType);
sb.append("\""+name+"\":");
objToJsonPrecess(sb,actualType);
sb.append(",");
}
// 获取集合List元素,转json
private static void getListEle(StringBuffer sb, Object obj, Field curField, String name, Class<?> curFieType) throws Exception {
// 当前集合的泛型类型
Type genericType = curField.getGenericType();
if (null != genericType) {
if (genericType instanceof ParameterizedType) {
ParameterizedType parametype = (ParameterizedType) genericType;
// 得到泛型里的class类型对象
Class<?> actualTypeArgument = (Class<?>)parametype.getActualTypeArguments()[0];
List<Object> curEleList = new ArrayList<Object>();
Object actualType = actualTypeArgument.newInstance();
//....actualType字段处理
curEleList.add(actualType);
curField.set(obj, curEleList);
sb.append("\""+name+"\":[");
objToJsonPrecess(sb,actualType);
sb.append("],");
}
}
}
//(Java反射)判断一个类型是Java本身的类型,还是用户自定义的类型
private static boolean isJavaClass(Class<?> clz) {
return clz != null && clz.getClassLoader() == null;
}
//日期转字符串
public static String dateToString(Date date, SimpleDateFormat sdf){
try {
if(date == null){
return "";
}else{
return sdf.format(date);
}
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}