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.DONEt = 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.DONEnextCharacter()) {
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\":\"open-open.com\"}"
System.out.println(jsonStr+":"+new JsonValidator().validate(jsonStr))
}
}
java进行大量数据校验时断网,将java虚拟机内存最大值调低到不大于服务器剩余的内存。该应用内存使用一直维持在2G内(快到2G时会触发垃圾回收的),从而不会导致总内存不足导致服务器kill掉进程。联网后继续查验。