代码之家  ›  专栏  ›  技术社区  ›  elifiner

如何使用RHNO将Java类中的方法添加到JavaScript中作为全局函数?

  •  13
  • elifiner  · 技术社区  · 14 年前

    我有一个简单的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) {
            // ....
        }
    }
    

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

    deal("1.3736", 100000);
    bid("1.3735", 500000);
    

    我现在唯一能想到的办法就是

    ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
    engine.put("utils", new Utils());
    

    然后使用 utils.deal(...) 在javascript代码中。我也可以用javascript为每个方法编写包装函数,但对于类的所有公共方法,应该有一种更简单的方法来自动完成这项工作。

    3 回复  |  直到 11 年前
        1
  •  7
  •   noah    14 年前

    我对犀牛不是很熟悉,但像这样的东西应该管用:

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

    只需循环查看 utils ,对于每个函数,创建一个调用它的全局函数。

    编辑:我在groovy脚本中完成了这项工作,但我必须在绑定中设置utils,而不是像在代码中那样在引擎上设置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()))
    
        2
  •  4
  •   Matthew Crumley    14 年前

    我不确定使用jsr-223 api该如何工作,但是使用rhino api,可以创建 FunctionObject 你要添加的方法如下。

    Class[] parameters = new Class[] { String.class, Integer.class };
    Method dealMethod = Utils.class.getMethod("deal", parameters);
    engine.put("deal", new FunctionObject("deal", dealMethod, scope));
    

    文件可在 https://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/FunctionObject.html .

    您可能需要引用rhino库来访问 函数对象 同学们,我不知道你怎么得到 scope 使用jsr-223api的 null 会起作用)。

        3
  •  0
  •   Community holdenweb    7 年前

    如果您使用rhino api而不是脚本引擎api,这是可能的,如下面的回答所述: https://stackoverflow.com/a/16479685/1089998 .

    与noah的答案相比,我更喜欢这种方法,因为它意味着在每次执行之前不需要执行随机的javascript代码。

    我这里有一个工作示例:

    https://github.com/plasma147/rhino-play