package com.gstarcad.fei.util;

/**
 * add by fengzf 2016-10-17
 * 用于校验一个字符串是否是合法的JSON格式
 *
 */
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;


 
public class JsonValidator {
 
    private static CharacterIterator it;
    private static char        c;
    private static int     col;
 
    public JsonValidator(){
    }
 
    /**
     * 验证一个字符串是否是合法的JSON串
     *
     * @param input 要验证的字符串
     * @return true-合法 ,false-非法
     */
    public static boolean validate(String input) {
    	if(StringUtils.isEmpty(input)){
    		return false;
    	}
        input = input.trim();
        boolean ret = valid(input);
        return ret;
    }
 
    private static  boolean valid(String input) {
        if ("".equals(input)) return true;
 
        boolean ret = true;
        it = new StringCharacterIterator(input);
        c = it.first();
        col = 1;
        if (!value()) {
            ret = error("value", 1);
        } else {
            skipWhiteSpace();
            if (c != CharacterIterator.DONE) {
                ret = error("end", col);
            }
        }
 
        return ret;
    }
 
    private static boolean value() {
        return literal("true") || literal("false") || literal("null") || string() || number() || object() || array();
    }
 
    private static boolean literal(String text) {
        CharacterIterator ci = new StringCharacterIterator(text);
        char t = ci.first();
        if (c != t) return false;
 
        int start = col;
        boolean ret = true;
        for (t = ci.next(); t != CharacterIterator.DONE; t = ci.next()) {
            if (t != nextCharacter()) {
                ret = false;
                break;
            }
        }
        nextCharacter();
        if (!ret) error("literal " + text, start);
        return ret;
    }
 
    private static boolean array() {
        return aggregate('[', ']', false);
    }
 
    private static boolean object() {
        return aggregate('{', '}', true);
    }
 
    private static boolean aggregate(char entryCharacter, char exitCharacter, boolean prefix) {
        if (c != entryCharacter) return false;
        nextCharacter();
        skipWhiteSpace();
        if (c == exitCharacter) {
            nextCharacter();
            return true;
        }
 
        for (;;) {
            if (prefix) {
                int start = col;
                if (!string()) return error("string", start);
                skipWhiteSpace();
                if (c != ':') return error("colon", col);
                nextCharacter();
                skipWhiteSpace();
            }
            if (value()) {
                skipWhiteSpace();
                if (c == ',') {
                    nextCharacter();
                } else if (c == exitCharacter) {
                    break;
                } else {
                    return error("comma or " + exitCharacter, col);
                }
            } else {
                return error("value", col);
            }
            skipWhiteSpace();
        }
 
        nextCharacter();
        return true;
    }
 
    private static boolean number() {
        if (!Character.isDigit(c) && c != '-') return false;
        int start = col;
        if (c == '-') nextCharacter();
        if (c == '0') {
            nextCharacter();
        } else if (Character.isDigit(c)) {
            while (Character.isDigit(c))
                nextCharacter();
        } else {
            return error("number", start);
        }
        if (c == '.') {
            nextCharacter();
            if (Character.isDigit(c)) {
                while (Character.isDigit(c))
                    nextCharacter();
            } else {
                return error("number", start);
            }
        }
        if (c == 'e' || c == 'E') {
            nextCharacter();
            if (c == '+' || c == '-') {
                nextCharacter();
            }
            if (Character.isDigit(c)) {
                while (Character.isDigit(c))
                    nextCharacter();
            } else {
                return error("number", start);
            }
        }
        return true;
    }
 
    private static boolean string() {
        if (c != '"') return false;
 
        int start = col;
        boolean escaped = false;
        for (nextCharacter(); c != CharacterIterator.DONE; nextCharacter()) {
            if (!escaped && c == '\\') {
                escaped = true;
            } else if (escaped) {
                if (!escape()) {
                    return false;
                }
                escaped = false;
            } else if (c == '"') {
                nextCharacter();
                return true;
            }
        }
        return error("quoted string", start);
    }
 
    private static boolean escape() {
        int start = col - 1;
        if (" \\\"/bfnrtu".indexOf(c) < 0) {
            return error("escape sequence  \\\",\\\\,\\/,\\b,\\f,\\n,\\r,\\t  or  \\uxxxx ", start);
        }
        if (c == 'u') {
            if (!ishex(nextCharacter()) || !ishex(nextCharacter()) || !ishex(nextCharacter())
                || !ishex(nextCharacter())) {
                return error("unicode escape sequence  \\uxxxx ", start);
            }
        }
        return true;
    }
 
    private static boolean ishex(char d) {
        return "0123456789abcdefABCDEF".indexOf(c) >= 0;
    }
 
    private static char nextCharacter() {
        c = it.next();
        ++col;
        return c;
    }
 
    private static void skipWhiteSpace() {
        while (Character.isWhitespace(c)) {
            nextCharacter();
        }
    }
 
    private static boolean error(String type, int col) {
        return false;
    }
    public static void main(String[] args){
    	String jsonStr = "{\"age\":30,\"name\":\"Michael\",\"baby\":[\"Lucy\",\"Lily\"]}";
        System.out.println(JsonValidator.validate(jsonStr));
    }
}
 
最近下载更多
LambertcoL  LV2 2019年4月20日
SDDDONG  LV11 2019年3月22日
zhaoan  LV3 2019年1月7日
hahaaaaa  LV2 2018年12月29日
张蒙666  LV2 2018年12月9日
hengfeiyu  LV1 2018年9月18日
feijiwjgq  LV6 2018年3月9日
唐僧洗头爱飘柔  LV22 2017年12月14日
wyx065747  LV67 2017年11月18日
最代码官方  LV167 2017年10月25日
最近浏览更多
小逸夜  LV4 2022年12月16日
1358849392  LV21 2022年11月11日
sleeper 2022年6月22日
暂无贡献等级
lakusazi 2021年3月26日
暂无贡献等级
双鱼座程序员7号  LV6 2021年3月25日
tonyhawkjm  LV22 2021年1月19日
zhangtian1997  LV10 2020年6月22日
今夜打火锅  LV3 2020年4月24日
JinghanHe  LV8 2020年2月24日
775794341  LV13 2019年12月17日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友