使用Java中的ScriptEngine调用自定义脚本函数

时间:2014-01-13 10:22:48

标签: java scriptengine jsr223 javax.script

我在用python,groovy和javascript编写的不同脚本文件上有相同的自定义函数和相同的名称。用户可以选择其中一个要使用的脚本。我想以通用方式调用这些脚本中的函数。

  ScriptEngineManager manager = new ScriptEngineManager();
  ScriptEngine engine = manager.getEngineByName("python");
  Bindings bindings = engine.createBindings();

  engine.eval(new FileReader("C:/Users/Cgr/Desktop/CustomPython.py");
  Invocable inv = (Invocable) engine;

  System.out.println(inv.invokeFunction("customConcatFunc", "str1", "str2"));

通过这种方式我可以调用我的函数甚至将ScriptEngineManager参数更改为“javascript”或“groovy”,并使用“CustomJs.js”或“Customgroovy.groovy”更改阅读器文件。

但是,我想知道有没有办法在不使用invokeFunction的情况下调用函数,如下所示:

首先,评估脚本并将结果放在绑定上,然后在此对象上调用函数。

   bindings.put("x", "str1");
   bindings.put("y", "str2");
   bindings.put("script", engine.eval(new FileReader("C:/Users/Cgr/Desktop/CustomgrPython.py")));

   engine.eval("script.customConcatFunc(x,y)", bindings);

那么,如果有这样的方式或有其他建议,这对我来说是最通用的方式吗?

1 个答案:

答案 0 :(得分:0)

以下方法可能有助于避免调用invokeFunction

@Test
public void test60_ScriptEngineTest()
        throws URISyntaxException, ScriptException, NoSuchMethodException, FileNotFoundException {

    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("groovy");
    Compilable compilable = (Compilable) engine;
    Bindings bindings = engine.createBindings();

    URL url=getClass().getResource("/data-encoder-dir/testFunc.groovy");
    File script =new File(url.toURI());
    Reader reader = new FileReader(script);
    CompiledScript compiledScript = compilable.compile(reader);

    bindings.put("x", 5011);
    String result = (String) compiledScript.eval(bindings);
    assertEquals(result, "5011");

}

附加了一个groovy文件(在/data-encoder-dir/testFunc.groovy中):

public String testFunc(Integer bd) {
    return bd.toString();
}

testFunc(x)

PS:我正在使用groovyjavascript方案或兼容的其他java脚本引擎将遵循相同的路线。