0

我正在使用 jdk11,graal.js 脚本引擎。

我们得到两个 json 字符串消息,一个有规则/条件(jsRules),另一个有消息。如果 message 中的值满足 jsRules 中的条件,则它应该评估为 1 else 0 。

因此,例如在下面的代码中,字符串“消息”code: CU_USER因此具有 jsRules 条件

header.code == 'CU_USER'

应该已经满足,因此下面的 eval 应该打印 1 ,但它给出了 0。请解释导致这种行为的原因以及如何获得所需的行为?.

public static void process()
{
    int eval =-2 ;
    String jsRules = "{(header.code == 'CU_USER' || header.subcode == 'SD_CODE')?1:0}";
    String message = "{code:'CU_USER'}";
    
    ScriptEngine graalEngine = new ScriptEngineManager().getEngineByName("Graal.js");
    //graalEngine.put("header",message);
    try {
        graalEngine.eval("var header = unescape(" + message + ")");
        eval = (int)graalEngine.eval(jsRules);
        System.out.println("Eval value::  "+eval);
    } catch (ScriptException e) {
        e.printStackTrace();
    }
}
4

1 回答 1

2

unescape({code:'CU_USER'})当 unescape 需要一个字符串时,您调用。因此,您作为参数提供的对象被转换为字符串([object Object]实际上是),因此headerJavaScript 端的变量包含一个字符串,而不是您期望的对象。

解决方案是简单地删除unescape, 即graalEngine.eval("var header = " + message);改用。


另一种解决方案是传入一个 Java 对象。您似乎已经使用注释掉的graalEngine.put("header",message);行进行了尝试。请注意,我想不想传入 Java 字符串;您通常想要传入的是具有code字段的 Java 对象。请注意,要使其正常工作,您需要启用对hostAccess引擎的权限(有关更多详细信息,请查看https://github.com/graalvm/graaljs/blob/master/docs/user/ScriptEngine.md)。

解决方案草案:

public static class MyMessageObj {
  public String code = "CU_USER";
}

ScriptEngine graalEngine = new ScriptEngineManager().getEngineByName("graal.js");
Bindings bindings = graalEngine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("polyglot.js.allowHostAccess", true);
graalEngine.put("header", new MyMessageObj());
eval = (int) graalEngine.eval(jsRules);

于 2020-11-09T10:25:16.190 回答