如何使用Rhino在Javascript中将Java类中的方法添加为全局函数?

eli*_*ner 13 javascript java rhino

我有一个简单的Java类,它有一些方法:

public class Utils {
    public void deal(String price, int amount) {
        // ....
    }
    public void bid(String price, int amount) {
        // ....
    }
    public void offer(String price, int amount) {
        // ....
    }
}
Run Code Online (Sandbox Code Playgroud)

我想创建这个类的一个实例,并允许Javascript代码直接调用方法,如下所示:

deal("1.3736", 100000);
bid("1.3735", 500000);
Run Code Online (Sandbox Code Playgroud)

我现在能想到的唯一方法就是使用

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
engine.put("utils", new Utils());
Run Code Online (Sandbox Code Playgroud)

然后utils.deal(...)在Javascript代码中使用.我也可以在Javascript中为每个方法编写包装函数,但应该有一种更简单的方法来自动为类的所有公共方法执行此操作.

noa*_*oah 7

我对Rhino并不熟悉,但这样的事情应该有效:

for(var fn in utils) {
  if(typeof utils[fn] === 'function') {
    this[fn] = (function() {
      var method = utils[fn];
      return function() {
         return method.apply(utils,arguments);
      };
    })();
  }
}
Run Code Online (Sandbox Code Playgroud)

只需循环遍历属性utils,并为每个函数创建一个调用它的全局函数.

编辑:我在Groovy脚本中工作,但我必须在绑定中设置utils,而不是在代码中的引擎上:

import javax.script.*

class Utils {
   void foo(String bar) {
      println bar
   }   
}

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");

engine.eval("""
for(var fn in utils) {
  if(typeof utils[fn] === 'function') {
    this[fn] = (function() {
      var method = utils[fn];
      return function() {
         return method.apply(utils,arguments);
      };
    })();
  }
}

foo('foo'); // prints foo, sure enough
""",new SimpleBindings("utils":new Utils()))
Run Code Online (Sandbox Code Playgroud)