Java JSON解析器解析含原生JS调用的内容失败,如何解决?
你遇到的解析失败是因为待解析内容不属于标准JSON格式,而是JavaScript对象字面量,存在两处不符合JSON规范的问题:
- 所有键名没有使用双引号包裹
cb字段的值是需要浏览器运行时执行的JS表达式,不属于JSON支持的字符串、数字、布尔值、数组、对象、null六种基础类型
以下是三种可行的适配方案:
方案1:使用Java内嵌JS引擎解析(最稳定,支持读取所有字段)
可以用GraalJS、Rhino等Java支持的JS运行引擎,直接把这段内容作为JS代码执行,提前模拟好浏览器的location对象即可拿到完整的对象数据,示例代码如下:
// GraalJS 依赖(Maven) // <dependency> // <groupId>org.graalvm.js</groupId> // <artifactId>js</artifactId> // <version>22.3.0</version> // </dependency> import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; public class ParseJsObjectDemo { public static void main(String[] args) { // 待解析的JS对象内容 String jsObjStr = "{\n" + " data: {\n" + " data1: {\n" + " plugins: ['voip', 'speed', 'act', 'capacity'],\n" + " last: \"~last~\",\n" + " unit: \"~units~\",\n" + " sid: '~sessionid~',\n" + " by: \"~by~\"\n" + " }\n" + " },\n" + " cb: location.protocol + \"//\" + location.host,\n" + " thresholds: ['default'],\n" + " calendars: ['default']\n" + "}"; // 提前模拟浏览器环境的location对象,可根据实际需求设置对应值 String mockBrowserEnv = "const location = {protocol: 'https:', host: 'www.example.com'};"; try (Context jsContext = Context.create("js")) { // 先注入模拟的浏览器环境变量 jsContext.eval("js", mockBrowserEnv); // 执行JS代码拿到对象,加括号是为了避免解析为代码块 Value parseResult = jsContext.eval("js", "(" + jsObjStr + ")"); // 读取字段示例 String cbValue = parseResult.getMember("cb").asString(); Value data1 = parseResult.getMember("data").getMember("data1"); String sidValue = data1.getMember("sid").asString(); System.out.println("cb字段值:" + cbValue); System.out.println("sid字段值:" + sidValue); } } }
方案2:文本预处理后用标准JSON库解析(适合不需要cb字段的场景)
如果不需要读取cb字段的值,可以通过简单的字符串替换把内容转换为标准JSON,再用Jackson、Fastjson等常规JSON库解析:
- 把所有单引号替换为双引号
- 给所有未加双引号的键名包裹双引号
- 把
cb: location.protocol + "//" + location.host,整段替换为cb: "",
处理完成后的内容就符合JSON规范,可以直接用常规解析器解析。
方案3:开启JSON库的宽松解析特性
常用JSON库都支持宽松解析模式,比如Jackson开启以下特性后可以解析无引号键名、单引号值的非标准JSON:
JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES:允许键名不加双引号JsonParser.Feature.ALLOW_SINGLE_QUOTES:允许值使用单引号包裹
开启后仍需要提前把cb字段的表达式替换为合法JSON值,才能完成解析。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

