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就用在这里,可以看到这里就是调的parseObjectJSONObject object = new JSONObject();return this.parseObject(object, fieldName);case 14: //这里就是调的parseArrayJSONArray 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;}}