fastjson中JSONObject.parse⽅法使⽤注意
今天遇到有同事在使⽤fastjson的JSONObject时,直接在parse⽅法中传⼊了⼀个⾮json格式的字符串,造成有时候报错,有时候⼜能正常返回。
问题现象
当你传⼊⼀个数值类型时,可以正常解析,当你传⼊⼀个⾮数值类型时,解析就报错了。
public class TestJson {
public static void main(String[] args){
Object parse = JSONObject.parse("12345678");
System.out.println(parse +", classType: "+ Class());
Object parse1 = JSONObject.parse("A12345678");
System.out.println(parse1 +", classType: "+ Class());
}
}
12345678, classType:class java.lang.Integer
Exception in thread "main" com.alibaba.fastjson.JSONException: syntax error, pos 1, json : A12345678
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1436)
at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1322)
at com.alibaba.fastjson.JSON.parse(JSON.java:152)
at com.alibaba.fastjson.JSON.parse(JSON.java:162)
at com.alibaba.fastjson.JSON.parse(JSON.java:131)
at com.ykc.TestJson.main(TestJson.java:12)
Process finished with exit code 1
其实遇到这个问题时,令我奇怪的是这两个⽅法都应该报错,因为我⼀直认为这个⽅法应该只能解析Json格式的字符串才对。
PS:我完全不知道这位同事是怎么想的,为什么要⽤parse去解析⼀个⾮Json的格式的字符串。。。
简单翻了⼀下源码,主要就是这个⽅法,发现原来解析时还兼容了⼀些其他类型的参数,具体源码就不看了,也没什么特别难以理解的。
public final void nextToken(){
sp =0;
for(;;){
pos = bp;
if(ch =='/'){
skipComment();
continue;
}
if(ch =='"'){
scanString();
return;
}
if(ch ==','){
next();
token = COMMA;
return;
}
//⽀持数值
if(ch >='0'&& ch <='9'){
scanNumber();
return;
parse error怎么解决}
//这个是负号的意思。。。所以还⽀持负数
//这个是负号的意思。。。所以还⽀持负数
if(ch =='-'){
scanNumber();
return;
}
switch(ch){
case'\'':
if(!isEnabled(Feature.AllowSingleQuotes)){
throw new JSONException("Feature.AllowSingleQuotes is false");
}
scanStringSingleQuote();
return;
case' ':
case'\t':
case'\b':
case'\f':
case'\n':
case'\r':
next();
break;
//还有⼀些true,false,null这样的
case't':// true
scanTrue();
return;
case'f':// false
scanFalse();
return;
case'n':// new,null
scanNullOrNew();
return;
case'T':
case'N':// NULL
case'S':
case'u':// undefined
scanIdent();
return;
case'(':
next();
token = LPAREN;
return;
case')':
next();
token = RPAREN;
return;
case'[':
next();
token = LBRACKET;
return;
case']':
next();
token = RBRACKET;
return;
case'{':
next();
token = LBRACE;
return;
case'}':
next();
token = RBRACE;
return;
case':':
next();
token = COLON;
return;
case';':
case';':
next();
token = SEMI;
return;
case'.':
next();
token = DOT;
return;
case'+':
next();
scanNumber();
return;
case'x':
scanHex();
return;
default:
if(isEOF()){// JLS
if(token == EOF){
throw new JSONException("EOF error");
}
token = EOF;
pos = bp = eofPos;
}else{
if(ch <=31|| ch ==127){
next();
break;
}
lexError("illegal.char", String.valueOf((int) ch));
next();
}
return;
}
}
}
看⼀下代码执⾏效果
public class TestJson {
public static void main(String[] args){
Object parse1 = JSONObject.parse("true");
System.out.println(parse1 +", classType: "+ Class());
Object parse2 = JSONObject.parse("1");
System.out.println(parse2 +", classType: "+ Class());
Object parse3 = JSONObject.parse("-1");
System.out.println(parse3 +", classType: "+ Class());
Object parse4 = JSONObject.parse("1.1");
System.out.println(parse4 +", classType: "+ Class());
Object parse5 = JSONObject.parse("null");
System.out.println(parse5);
}
}
true, classType:class java.lang.Boolean
1, classType:class java.lang.Integer
-
1, classType:class java.lang.Integer
1.1, classType:class java.math.BigDecimal
null
Process finished with exit code 0
感觉这个⽅法有点⼩坑啊,关键⾚裸裸的⽅法居然⼀点说明也没有。。。
public static Object parse(String text){
return parse(text, DEFAULT_PARSER_FEATURE);
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。