Mozilla Rhino调用NativeJSON.parse抛RhinoException无行号问题求解
Rhino解析JSON异常无法获取行号列号的解决方案
根因说明
- Rhino内置的
NativeJSON.parse方法实现未将输入JSON字符串的位置信息关联到抛出的RhinoException中,哪怕开启FEATURE_LOCATION_INFORMATION_IN_ERROR特性也不会自动填充行号、列号字段,属于接口设计的预期行为,并非特性损坏。 - 该方法仅把输入当成纯字符串处理,没有走Rhino常规的脚本位置跟踪逻辑,所以返回的错误属性全为0。
可行解决方案
方案1:改用脚本执行方式调用JSON.parse(最推荐,无额外依赖)
将JSON解析逻辑包装为Rhino可识别的脚本片段,指定源名称和起始行号,Rhino的脚本执行引擎会自动跟踪错误位置:
Context cx = Context.enter(); try { Scriptable scope = cx.initStandardObjects(); // 传入的JSON字符串s会被自动转义,避免注入风险 String parseScript = "JSON.parse(" + Context.javaToJS(s, scope) + ")"; // 第三个参数填你的JSON文件路径/标识,第四个参数为起始行号,固定填1即可 Object parseResult = cx.evaluateString(scope, parseScript, "custom_json_source", 1, null); } catch (RhinoException e) { // 此处可正常获取到错误位置信息 int errorLine = e.lineNumber(); int errorColumn = e.columnNumber(); String errorMsg = e.getMessage(); } finally { Context.exit(); }
方案2:前置用第三方JSON库做格式校验
如果必须直接调用NativeJSON.parse,可以先引入Jackson、Fastjson等JSON解析库做前置校验,提前拿到错误位置:
// 示例用Jackson校验 ObjectMapper mapper = new ObjectMapper(); try { mapper.readTree(s); // 格式合法再调用Rhino解析 NativeJSON.parse(cx, scope, s, null); } catch (JsonProcessingException e) { // 直接从Jackson异常中拿到行号列号 int line = e.getLocation().getLineNr(); int column = e.getLocation().getColumnNr(); // 自行包装异常即可 }
方案3:修改Rhino源码(仅特殊场景使用)
如果需要深度定制,可修改NativeJSON.java中的解析逻辑,在抛出语法错误时将解析器内部记录的行号、列号传入RhinoException构造方法,重新编译Rhino依赖即可。
内容的提问来源于stack exchange,提问作者Petr
相关产品推荐
相关产品推荐

