自定义json验证外加返回json中key的集合

注:
1.Bean类为继承自Map的封装类,可自由改动;
2.JsonUtils.toBean()为封装自org.json包,可自由更改
/**
 * 获取key.key集合
 * @param json json字符串
 * @param existLabel 存入key.key的集合
 * @param curLabel 当前key是什么
 */
public static void getJsonLabel(String json, Set<String> existLabel, String curLabel) {
    //判断是否是json格式
    if (!checkIsJson(json)) return;
    Bean bean;
    //判断是否为null和”“
    if (json == null || json.isEmpty()) {
        return;
    }
    //1.第一个字符为【,则代表为数组
    //2.第一个字符为{,则代表为对象
    if (json.substring(0, 1).equals("[")) {
        //第二个字符为{,则代表为对象数组
        if (json.substring(1, 2).equals("{")) {
            bean = JsonUtils.toBeanList(json).get(0);
        } else {
            return;
        }
    } else if (json.substring(0, 1).equals("{")) {
        bean = JsonUtils.toBean(json);
    } else {
        return;
    }
    //对象中key的数量
    int keyNum = bean.keySet().size();
    if (keyNum > 0) {
        for (Object keyObj : bean.keySet()) {
            //前缀
            String labelPrefix = "";
            //判断当前key是否为空
            if (curLabel.isEmpty()) {
                //为空的话前缀则为当前key
                labelPrefix = keyObj.toString();
            } else {
                //不为空前缀则为key.当前key
                labelPrefix = curLabel + "." + keyObj.toString();
            }
            //将前缀填入set集合
            existLabel.add(labelPrefix);
            //获取值
            Object obj = bean.get(keyObj);
            if (obj != null) {
                //1.是否为对象
                //2.是否为数组
                //3.在为字符串的情况下则进行json验证代码
                if (obj instanceof Bean) {
                    getJsonLabel(JsonUtils.toJson((Bean) bean.get(keyObj)), existLabel, labelPrefix);
                } else if (obj instanceof ArrayList) {
                    getJsonLabel(JsonUtils.toJson((ArrayList) bean.get(keyObj)), existLabel, labelPrefix);
                } else if ((obj.toString().substring(0, 1).equals("{")
                        || obj.toString().substring(0, 2).equals("[{"))
                        && checkIsJson(obj.toString())) {
                    getJsonLabel(obj.toString(), existLabel, labelPrefix);
                }
            }
        }
    }
}


/**
 * 判断规则
 * 引号中的内容全部跳过,若想继续判断,可使用递归方式
 * 为】时验证前方到【之间的,有多少,是否与{}对个数相差1
 * :和:之间相差1个,
 * @return
 */
public static boolean checkIsJson(String json) {
    Deque deque = new LinkedList();

    //需要添加到栈中的符号
    String inDeque = "{[,:";
    //判断是否为json验证的符号
    String needSymbol = "{}[],:\"";

    //判断是否为引号
    boolean isQuotationMarks = false;
    //判断数组是否为多个对象,对象即{}
    boolean isOpenArrayCount = false;
    //数组中对象的个数
    int bracesAmount = 0;
    for (int i = 0; i < json.length(); i++) {
        //获取单个字符
        String s = json.substring(i, i + 1);

        //判断单个字符是否为json验证所需的符号
        if (needSymbol.indexOf(s) == -1) {
            continue;
        }

        //判断是否为引号
        if (s.equals("\"")) {
            if (!isQuotationMarks) {
                isQuotationMarks = true;
            } else {
                isQuotationMarks = false;
            }
        }

        //引号之间的内容全部跳过
        if (isQuotationMarks) {
            continue;
        }

        //将需要压入栈中的内容填入栈中
        if (inDeque.indexOf(s) > -1) {
            //判断数组中是否为对象
            if ("{".equals(s) && "[".equals(deque.peekFirst())) {
                isOpenArrayCount = true;
            }
            deque.addFirst(s);
        }

        //对象出栈
        if (s.equals("}")) {
            //如果是数组对象,则开始计数
            if (isOpenArrayCount) {
                bracesAmount++;
            }
            //冒号的数量
            int commaAmount = 0;
            //都好的数量
            int colonAmount = 0;
            //循环的次数为栈的大小
            int cycleNum = deque.size();
            for (int j = 0; j < cycleNum; j++) {
                //查看栈首是否为逗号
                if (",".equals(deque.peekFirst())) {
                    commaAmount++;
                }
                //查看栈首是否为冒号
                if (":".equals(deque.peekFirst())) {
                    colonAmount++;
                }
                //如果栈首是左括号就停止循环,并弹出
                if ("{".equals(deque.removeFirst().toString())) {
                    break;
                }
            }
            //1.逗号数量为0,即代表花括号中只有一个值
            //2.逗号数量不为1,即代表逗号数量要比冒号数量少1
            if (commaAmount != 0 && commaAmount + 1 != colonAmount) {
                return false;
            }
        }

        //数组出栈
        if (s.equals("]")) {
            //对象之间逗号的数量
            int commaAmount = 0;
            //判断是否为对象数组
            boolean isObjArray = false;
            //循环的次数
            int cycleNum = deque.size();
            for (int j = 0; j < cycleNum; j++) {
                //判断栈首是否为右花括号,若是则代表为[{},{}]结构,若不是则代表为[,,]结构
                if (j == 0 && "}".equals(deque.peekFirst())) {
                    //是对象数组
                    isObjArray = true;
                    //关闭对象判断,直至下次开启
                    isOpenArrayCount = false;
                }
                //栈首是否为逗号
                if (",".equals(deque.peekFirst())) {
                    commaAmount++;
                }
                //如果栈首是左中括号就停止循环,并弹出
                if ("[".equals(deque.removeFirst().toString())) {
                    break;
                }
            }
            //只有在是对象数组的情况下需要判断,逗号的数量比对象数量少1
            if (isObjArray && bracesAmount != 0 && commaAmount + 1 != bracesAmount) {
                return false;
            }
            //对象数量清空
            bracesAmount = 0;
        }
    }

    //若在json字符串循环完毕后栈中还存在数据,则代表json不是标准格式
    if (deque.size() != 0) {
        return false;
    }

    return true;
}

public static void main(String[] args) {
    //String json = "{\"state\":{\"code\":10001,\"message\":\"{访:问a:问}\",\"timestamp\":1647398784788},\"body\":{}}";
    /*String json = "{\n" +
            "    \"definitions\": {\n" +
            "        \"address\": {\n" +
            "            \"type\": \"object\",\n" +
            "            \"properties\": {\n" +
            "                \"street_address\": \"{ 'type': 'string' }\",\n" +
            "                \"city\":           { \"type\": \"string\" },\n" +
            "                \"state\":          { \"type\": \"string\" }\n" +
            "            },\n" +
            "            \"required\": [\"street_address\", \"city\", \"state\"]\n" +
            "        }\n" +
            "    },\n" +
            "    \"type\": \"object\",\n" +
            "    \"properties\": {\n" +
            "        \"billing_address\": { \"$ref\": \"#/definitions/address\" },\n" +
            "        \"shipping_address\": { \"$ref\": \"#/definitions/address\" }\n" +
            "    }\n" +
            "}";*/
    String json = "{ \"type\": \"string\" }";
    JsonUtils.toBean(json);
    Set<String> existLabel = new HashSet<>();
    getJsonLabel(json, existLabel, "");
    System.out.println(existLabel);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值