原本項目用的jackson,有的地方有混入了 fastjson,還把JSON.parseArray 用錯了,着實鬱悶了我一把
原來這字符串挺長,瘦身了一下,這裏的關鍵是 這 str 是兩個對象啊,而且對象類型都一樣,這麼用是要鬧哪般
@Test
public void testJson() throws IOException {
String str = "[{\"id\":28,},{\"id\":29}]";
String[] strs = str.split("[{|}]");
String second = ",{" + strs[3] + "}";
second = "";
str = strs[0] + "{" + strs[1] + "}" + second + strs[4];
List<Object> jobs = JSON.parseArray(str,
new Type[] { HiveJob.class });
}
運行這段代碼會收穫如下異常:
Exception in thread "main" com.alibaba.fastjson.JSONException: syntax error
at com.alibaba.fastjson.parser.DefaultJSONParser.parseArray(DefaultJSONParser.java:713)
at com.alibaba.fastjson.JSON.parseArray(JSON.java:353)
這個異常產生在 com.alibaba.fastjson.parser.DefaultJSONParser.parseArray(Type[] types) :
if (lexer.token() != JSONToken.RBRACKET) {
throw new JSONException("syntax error");
}
說下此處的上下文,這是一個解析器 DefaultJSONParser 調用的方法,參數就是測試中傳入的Type數組。
在這之前,創建解析器時已經將要解析的字符串存入,在這裏只要根據 type 創建相應的對象,找出他的屬性,爲它賦值。
將所有對象放到 list 返回。結構很清晰,deserialize 過程還是蠻複雜,要一個一個取出字符,分別記錄字符和它的類型,你是大括號啊還是引號啊等,
並且還要猜下一個字符可能是什麼,應該是什麼,如果應該是b,你是a ,一個異常就出來了,上面這個異常就是這麼出來的。
根據 types數組創建對象,已經遍歷完了,字符串卻沒完。就上面例子來說 ,type 遍歷結束後,下一個字符就應該是 ] ,但字符串有兩個對象啊,
結果下一個字符是 {,結果上面這個Exception就被丟出來了。
很簡單,但我要花時間找到這個字符串,查資料,無果,再去debug,着實浪費生命。
發現 fastjson 的API有點寒磣啊。
public Object[] parseArray(Type[] types) {
for (int i = 0; i < types.length; ++i) {
Object o = ...;
list.add(o);
}
if (lexer.token() != JSONToken.RBRACKET) {
throw new JSONException("syntax error");
}
lexer.nextToken(JSONToken.COMMA);
return list;
}
順便喵了一眼,fastjson 昨天有更新,非得用 fastjson 的同學快看看,是不是更 fast 了呢。
https://github.com/alibaba/fastjson