【问题标题】:JavaScript function invocation in Java CodeJava 代码中的 JavaScript 函数调用
【发布时间】:2013-03-13 15:08:49
【问题描述】:

我将一个函数从 JavaScript 文件传递​​到 Java 代码中。 JavaScript 函数如下所示:

entity.handler = function(arg1, arg2) {
    //do something
};

在 Java 代码中,该类实现了Scriptable 接口。而当我调用 JavaScript 时,实际上在 Java 中调用了以下方法:

Scriptable.put(java.lang.String s, org.mozilla.javascript.Scriptable scriptable, java.lang.Object o)

我的情况在哪里:

s = '处理程序';

scriptable - 类型为com.beanexplorer.enterprise.operations.js.ScriptableEntity的对象

o - 实际上是一个函数,它的类型是org.mozilla.javascript.gen.c15( o instanceof Scriptable ) 在调试器中返回 true

Scriptable.put() 方法实现中,我想将操作委托给“o”对象:

SomeClass.invoke( new SomeListener(){
    @override
    public void someAction(int arg1, float arg2) {
       //here I need to delegate to the 'o' object.
       //do something looked like: 
       o.call(arg1, arg2); // have no idea how to do it, if it's possible.
    }
}

我该怎么做?我找不到我的案例所需的任何示例。

谢谢。

编辑,解决方案: 实际上 o - 可以转换为 Function。因此,以下解决方案有所帮助:

@Override
put(java.lang.String s, org.mozilla.javascript.Scriptable scriptable, java.lang.Object o) {
    ....
    final Function f = ( Function )o;
    final SomeInterface obj = new ...;
    obj.someJavaMethod( Object someParams, new SomeJavaListener() { 
        @Override
    public void use(Object par1, Object par2) throws Exception {
        Context ctx = Context.getCurrentContext();
        Scriptable rec = new SomeJavaScriptableWrapperForObject( par1);
            f.call( ctx, scriptable, scriptable, new Object[] { rec, par2 } );
        }
});

【问题讨论】:

  • 来自API doc of ScriptableHost system implementors may find it easier to extend the ScriptableObject class rather than implementing Scriptable when writing host objects. 我会试试...
  • 如果我没听错的话,您提出通过 Java 类扩展 ScriptableObject 而不是实现接口。但无论如何我必须重写 put 方法,因为标准实现不适合。结果,我看不到扩展 ScriptableObject 类而不是实现接口的任何好处。
  • 你的论点部分有效。但是我会这样做,因为这样做,你的代码会更干净,它可能有助于发现问题的原因,这样你就不必编写所有代码来开始......你只需要然后覆盖“有用”的方法......
  • 请问您到底想做什么?不确定,因为您的问题模棱两可。据我了解,您希望通过允许用户为entity.handler 传递任意代码来使您的程序可编写脚本,该代码必须是具有 arity 2 的函数。这就是您想要的吗?
  • 是的,你是对的。最初它不是我的代码。主要目的 - 在 JavaScript 中编写处理程序而不知道它们是如何实际处理的。

标签: java javascript rhino invocation


【解决方案1】:

我设法通过以下代码运行了您的 Javascript:

public class Main {

    public static void main(String[] args) {
        new ContextFactory().call(new ContextAction(){

            @Override
            public Object run(Context ctx) {
                Scriptable scope = ctx.initStandardObjects();
                try {
                    Scriptable entity = ctx.newObject(scope);

                    scope.put("console", scope, Context.javaToJS(System.out, scope));
                    scope.put("entity", scope, entity);

                    ctx.evaluateReader(
                        scope,
                        new InputStreamReader(Main.class.getResourceAsStream("/handler.js")),
                        "handler.js", 1, null);

                    Function handler = (Function) entity.get("handler", entity);
                    Object result = handler.call(ctx, scope, scope, new Object[] {"Foo", 1234});

                    System.out.println("Handler returned " + result);
                } catch (Exception e) {
                    e.printStackTrace(System.err);
                }
                return null;
            }
        });

    }
}

以下脚本必须在您的 CLASSPATH 上的 handler.js 中可用:

entity.handler = function(arg1, arg2) {
    console.println("Hello world from the JS handler");
    return 42;
}

【讨论】:

    猜你喜欢
    • 2012-07-29
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    相关资源
    最近更新 更多