
/** |
* 用于校验一个字符串是否是合法的JSON格式 |
* |
*/ |
import java.text.CharacterIterator; |
import java.text.StringCharacterIterator; |
public class JsonValidator { |
private CharacterIterator it; |
private char c; |
private int col; |
public JsonValidator(){ |
} |
/** |
* 验证一个字符串是否是合法的JSON串 |
* |
* @param input 要验证的字符串 |
* @return true-合法 ,false-非法 |
*/ |
public boolean validate(String input) { |
input = input.trim(); |
boolean ret = valid(input); |
return ret; |
} |
private 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 boolean value() { |
return literal("true") || literal("false") || literal("null") || string() || number() || object() || array(); |
} |
private 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 boolean array() { |
return aggregate('[', ']', false); |
} |
private boolean object() { |
return aggregate('{', '}', true); |
} |
private 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 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 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 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 boolean ishex(char d) { |
return "0123456789abcdefABCDEF".indexOf(c) >= 0; |
} |
private char nextCharacter() { |
c = it.next(); |
++col; |
return c; |
} |
private void skipWhiteSpace() { |
while (Character.isWhitespace(c)) { |
nextCharacter(); |
} |
} |
private boolean error(String type, int col) { |
System.out.printf("type: %s, col: %s%s", type, col, System.getProperty("line.separator")); |
return false; |
} |
public static void main(String[] args){ |
String jsonStr = "{\"website\":\"oschina.net\"}"; |
System.out.println(jsonStr+":"+new JsonValidator().validate(jsonStr)); |
} |
} |
//源代码片段来自云代码http://yuncode.net |
|



