有没有Java中可用的Nashorn的ScriptObjectMirror的公共且具体的实例?

6
我基本上想要去:
ScriptObjectMirror myObj = new ConcreteScriptObjectMirror();

然后调用一些JS,如下所示,其中myObj为参数:

function myJSFunc(param) { 
    with(param) { 
        return paramProperty; 
    } 
} 

我正在进行这个操作,但Nashorn报错:

TypeError: Cannot apply "with" to non script object

因此,我传递的Java对象需要是ScriptObjectMirror的实例。

3个回答

3

我曾经遇到过同样的问题,如果你还没有找到答案的话,我认为以下代码片段可能会有你想要的东西。我正在使用javax.script.SimpleBindings将对象传递给JavaScript函数。

import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;

public class Demo {

    public static void main(String[] args) throws Exception {
        Demo demo = new Demo();
        String result = demo.execute();
        System.out.println("full name is " + result);
    }

    public String execute() throws ScriptException, NoSuchMethodException {
        final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
        final Compilable compilable = (Compilable) engine;
        final Invocable invocable = (Invocable) engine;

        final String statement = "function fetch(values) { return values['first_name'] + ' ' + values['last_name']; };";
        final CompiledScript compiled = compilable.compile(statement);

        compiled.eval();

        SimpleBindings test = new SimpleBindings();
        test.put("first_name", "John");
        test.put("last_name", "Doe");

        FullName fullName = invocable.getInterface(FullName.class);
        return fullName.fetch(test);
    }

    public interface FullName {
      String fetch(SimpleBindings values);
    }
}

在我看来,目前Nashorn文档相当不好,因此希望这个翻译有所帮助。


1

由于ScriptObjectMirror是final类,您无法从该类继承。 Nashorn引擎使用ScriptObjectMirror将javascript对象传递到Java端,而不是相反。

在从Java代码调用javascript函数时,您只需将任意Java对象传递给该函数即可:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(new FileReader("myScript.js"));

Invocable invocable = (Invocable) engine;

Object result = invocable.invokeFunction("myJSFunc", "Peter Parker");
System.out.println(result);

查看此文章获取更多示例:http://winterbe.com/posts/2014/04/05/java8-nashorn-tutorial/


Nashorn不会在JS的"with"中接受任意Java对象。因此我有一个问题。 - Kong

0

我现在没有时间测试这个,但是在你将 myObj 传递给 Nashorn 引擎的时候,尝试使用 Java.from(foo)。

因此,在你的例子中,你可以尝试如下操作:

function myJSFunc(param) { 
    with(Java.from(param)) { 
        return paramProperty; 
    } 
} 

这可能是这样的情况,你正在传递一个Java对象(ScriptObjectMirror),而这是你的JavaScript对象的包装器,调用Java.from()将对其进行解包。
一些说明在这里: https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions(搜索java.from)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接