1、JSONObject和JSONArray的数据表示形式
JSONObject的数据是用 { } 来表示的,
例如: {"name":"John","age":30,"city":"New York"}
而JSONArray,顾名思义是由JSONObject构成的数组,用 [ { } , { } , … , { } ] 来表示
例如: [{"name":"John","age":30,"city":"New York"}] ;
2、解析json及可能遇到的问题
String str1 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
String str2 = "[{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}]";
JSONObject jsonObject = JSONObject.parseObject(str1);
JSONArray jsonArray = JSONArray.parseArray(str2);
jsonObject对象如下
解析jsonArray的对象如下:
如果执行下面的代码
String str1 = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
String str2 = "[{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}]";
JSONObject jsonObject = JSONObject.parseObject(str2);
JSONArray jsonArray = JSONArray.parseArray(str1);
则会抛异常,即对象形式的json不能用parseArray进行解析,数组形式的json也不能用parseObject进行解析。
3、解决方案
可以使用JSON.parse()方法,该方法会自动判断json的类型,然后调不同的方法进行反解析。若需要需要知道具体对象,通过如下的方式进一步判断就可以了
Object obj = JSON.parse(jsonString);
if (obj instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) obj;
} else if (obj instanceof JSONArray) {
JSONArray jsonArray = (JSONArray) obj;
}
}
JSON.parse()方法中判断json串是什么类型的代码如下:
public DefaultJSONParser(Object input, JSONLexer lexer, ParserConfig config) {
this.resolveStatus = 0;
this.derializer = new DefaultObjectDeserializer();
this.contextArray = new ParseContext[8];
this.contextArrayIndex = 0;
this.resolveTaskList = new ArrayList();
this.dateFormatPattern = JSON.DEFFAULT_DATE_FORMAT;
this.input = input;
this.lexer = lexer;
this.config = config;
this.symbolTable = config.getSymbolTable();
lexer.nextToken(12);
}
public void nextToken(int expect) {
while(true) {
switch (expect) {
case 2:
if (this.ch >= '0' && this.ch <= '9') {
this.sp = 0;
this.pos = this.bp;
this.scanNumber();
return;
}
if (this.ch == '"') {
this.sp = 0;
this.pos = this.bp;
this.scanString();
return;
}
if (this.ch == '[') {
this.token = 14;
this.ch = this.buf[++this.bp];
return;
}
if (this.ch == '{') {
this.token = 12;
this.ch = this.buf[++this.bp];
return;
}
case 3:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 13:
case 17:
case 18:
case 19:
default:
break;
case 4:
if (this.ch == '"') {
this.sp = 0;
this.pos = this.bp;
this.scanString();
return;
}
if (this.ch >= '0' && this.ch <= '9') {
this.sp = 0;
this.pos = this.bp;
this.scanNumber();
return;
}
if (this.ch == '[') {
this.token = 14;
this.ch = this.buf[++this.bp];
return;
}
if (this.ch == '{') {
this.token = 12;
this.ch = this.buf[++this.bp];
return;
}
break;
case 12: //默认传进来的的expect就是12,所以会走到这个分支里边,会根据json串的情况给token赋值不同的值
if (this.ch == '{') {
this.token = 12;
this.ch = this.buf[++this.bp];
return;
}
if (this.ch == '[') {
this.token = 14;
this.ch = this.buf[++this.bp];
return;
}
break;
case 14:
if (this.ch == '[') {
this.token = 14;
this.ch = this.buf[++this.bp];
return;
}
if (this.ch == '{') {
this.token = 12;
this.ch = this.buf[++this.bp];
return;
}
break;
case 15:
if (this.ch == ']') {
this.token = 15;
this.ch = this.buf[++this.bp];
return;
}
case 20:
if (this.ch == 26) {
this.token = 20;
return;
}
break;
case 16:
if (this.ch == ',') {
this.token = 16;
this.ch = this.buf[++this.bp];
return;
}
if (this.ch == '}') {
this.token = 13;
this.ch = this.buf[++this.bp];
return;
}
if (this.ch == ']') {
this.token = 15;
this.ch = this.buf[++this.bp];
return;
}
if (this.ch == 26) {
this.token = 20;
return;
}
}
if (this.ch != ' ' && this.ch != '\n' && this.ch != '\r' && this.ch != '\t' && this.ch != '\f' && this.ch != '\b') {
this.nextToken();
return;
}
this.ch = this.buf[++this.bp];
}
}
在解析的主代码如下
public Object parse(Object fieldName) {
JSONLexer lexer = this.getLexer();
switch (lexer.token()) {
case 2:
Number intValue = lexer.integerValue();
lexer.nextToken();
return intValue;
case 3:
Object value = lexer.decimalValue(this.isEnabled(Feature.UseBigDecimal));
lexer.nextToken();
return value;
case 4:
String stringLiteral = lexer.stringVal();
lexer.nextToken(16);
if (lexer.isEnabled(Feature.AllowISO8601DateFormat)) {
JSONScanner iso8601Lexer = new JSONScanner(stringLiteral);
if (iso8601Lexer.scanISO8601DateIfMatch()) {
return iso8601Lexer.getCalendar().getTime();
}
}
return stringLiteral;
case 6:
lexer.nextToken();
return Boolean.TRUE;
case 7:
lexer.nextToken();
return Boolean.FALSE;
case 8:
lexer.nextToken();
return null;
case 9:
lexer.nextToken(18);
if (lexer.token() != 18) {
throw new JSONException("syntax error");
}
lexer.nextToken(10);
this.accept(10);
long time = lexer.integerValue().longValue();
this.accept(2);
this.accept(11);
return new Date(time);
case 12: //token就用在这里,可以看到这里就是调的parseObject
JSONObject object = new JSONObject();
return this.parseObject(object, fieldName);
case 14: //这里就是调的parseArray
JSONArray array = new JSONArray();
this.parseArray(array, fieldName);
return array;
case 20:
if (lexer.isBlankInput()) {
return null;
}
case 5:
case 10:
case 11:
case 13:
case 15:
case 16:
case 17:
case 18:
case 19:
default:
throw new JSONException("TODO " + lexer.tokenName() + " " + lexer.stringVal());
case 21:
lexer.nextToken();
HashSet<Object> set = new HashSet();
this.parseArray(set, fieldName);
return set;
case 22:
lexer.nextToken();
TreeSet<Object> treeSet = new TreeSet();
this.parseArray(treeSet, fieldName);
return treeSet;
}
}