原本项目用的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 了呢。