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

如何将JavaScript函数传递给Java方法来充当回调(RHNO)

  •  9
  • sproketboy  · 技术社区  · 15 年前

    基本上,我尝试将JavaScript函数传递给Java方法,以作为对脚本的回调。

    我可以这样做,但我收到的对象是sun.org.mozilla.javascript.internal.explatedFunction,我看不到调用它的方法。

    有什么想法吗?

    以下是我目前为止的情况:

    var someNumber = 0;
    
    function start() {
       // log is just an log4j instance added to the Bindings
       log.info("started....");
       someNumber = 20;
    
        // Test is a unit test object with this method on it (taking Object as a param).
        test.callFromRhino(junk);
    }
    
    function junk() {
        log.info("called back " + someNumber);
    }
    
    4 回复  |  直到 12 年前
        1
  •  9
  •   McDowell rahul gupta    15 年前

    实现接口:

    import javax.script.*;
    
    public class CallBack {
      public void invoke(Runnable runnable) {
        runnable.run();
      }
    
      public static void main(String[] args) throws ScriptException {
        ScriptEngine js = new ScriptEngineManager().getEngineByExtension("js");
        js.getContext().setAttribute("callBack", new CallBack(),
            ScriptContext.ENGINE_SCOPE);
        js.eval("var impl = { run: function () { print('Hello, World!'); } };\n"
            + "var runnable = new java.lang.Runnable(impl);\n"
            + "callBack.invoke(runnable);\n");
      }
    }
    
        2
  •  7
  •   Daniel Martin    15 年前

    sun.org.mozilla.javascript.internal.InterpretedFunction 实现接口 sun.org.mozilla.javascript.Function . 该接口上有一个方法调用 call 这需要:

    • Context
    • Scriptable 用作范围
    • 脚本 用作 this 在函数内
    • 一个数组 Objects 这是函数的参数

    所以,我建议在Java中,将您传递的对象作为 sun.org.mozilla.javascript.函数 并打电话 呼叫 . 前两个参数可以是从Java开始使用的任何脚本来启动脚本。在这里,最后两个参数可以是 null new Object[0] .

        3
  •  2
  •   mogsie    15 年前

    解决方案实际上是在另一个脚本中调用它。这类作品:

    import javax.script.*;
    
    public class CallFunction {
    
        /**
         * @param args
         * @throws Exception oops!
         */
        public static void main(String[] args) throws Exception {
            ScriptEngine js = new ScriptEngineManager().getEngineByExtension("js");
            js.getContext().setAttribute("out", System.out, ScriptContext.ENGINE_SCOPE);
            Object a = js.eval(
                    "out.println('Defining function a...');" +
                    "function a() {out.println('hello from JavaScript!'); }" +
                    "function foobar() {out.println('in foobar() definition');}" +    
                    "out.println('Done!.');"
            );
    
            System.out.println(js.get("a")); // InterpretedFunction
            SimpleBindings bindings = new SimpleBindings();
            bindings.put("foobar",js.get("a"));
            js.eval("foobar();", bindings); // hello from JavaScript
            js.eval("foobar();"); // in foobar() definition
        }
    }
    

    当您返回对函数的引用时,需要请求引擎为您执行该函数。虽然不是很漂亮,但是让JS用一组特定的绑定为您eval()它实际上会为您完成这项工作。你需要注意你操作的变量属于正确的范围;我想在这里很容易出错。

        4
  •  1
  •   volhv    12 年前

    这个例子涵盖了用JavaScript实现Java接口。这也可以用于调用Java的JavaScript回调。

    
    
    package com.hal.research;
    
    import javax.script.*;
    
    public class CallFunction {
        /**
         * define contract for the callback 
         */
        static interface WhatEverYouWant {
            public String testMe(String a, String b);
        }
        /**
         * @param args
         */
        public static void main(String[] args) throws Exception {
            final ScriptEngineManager scriptManager = new ScriptEngineManager();
            final ScriptEngine js = scriptManager.getEngineByExtension("js");
            js.put("producer", new Object() {
                /**
                 * @param call is a callback to be invoked
                 */
                public void doSomethingWithIt(WhatEverYouWant call) {
                    System.out.println("invoke callback javascript...");
                    String result = call.testMe("a", "b");
                    // do something with the result ...
                    System.out.println("invoke callback...done, result: "+result);
                }
            });
            js.eval(  "var handler = {\"testMe\": function (a,b){return a + \" is concatenated to \"+ b;}};\n"
                    + "var callback = new Packages.com.hal.research.CallFunction.WhatEverYouWant(handler);\n"
                    + "producer.doSomethingWithIt(callback); ");
        }
    }