Json 格式化工具类



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 "";
        }
    }

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值