为Nashorn脚本引擎定义默认/全局Java对象?

时间:2015-07-06 01:06:11

标签: java nashorn

使用Java的Nashorn脚本引擎,我可以使用像这样的绑定在eval()的上下文中提供对象:

Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.put("rules", myObj); 
scriptEngine.eval("rules.someMethod('Hello')", scriptContext);

我希望能够通过提供默认对象来简化javascript,以便代替javascript:

rules.someMethod('Hello')

我可以写:

someMethod('Hello')

有没有办法实现这个目标? (someMethod是对象的方法,而不是静态方法)

1 个答案:

答案 0 :(得分:8)

您可以使用nashorn的Object.bindProperties扩展将任意对象的属性绑定到JS全局对象。这样,用户可以无需限定地从脚本调用“默认”对象上的方法(和访问属性)。 请参阅此处的https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-Object.bindProperties

中的Object.bindProperties文档

示例代码:

import javax.script.*;

public class Main {
   public static void main(String[] args) throws Exception {
       ScriptEngineManager m = new ScriptEngineManager();
       ScriptEngine e = m.getEngineByName("nashorn");

       // get JavaScript "global" object
       Object global = e.eval("this");
       // get JS "Object" constructor object
       Object jsObject = e.eval("Object");

       Invocable invocable = (Invocable)e;

       // calling Object.bindProperties(global, "hello");
       // which will "bind" properties of "hello" String object
       // to JS global object
       invocable.invokeMethod(jsObject, "bindProperties", global, "hello");

       // you're calling "hello".toUpperCase()"
       e.eval("print(toUpperCase())");
       // accessing bean property "empty" on 'hello' object
       e.eval("print(empty)");

       // just print all (enumerable) properties of global
       // you'll see methods, properties of String class
       // (which'd be called on "hello" instance when accessed)
       e.eval("for (var i in this) print(i)");
   }
}