如何在Java对象中解包由javascript(nashorn)返回的值?

8
我有以下程序,它在Java(nashorn)中执行JavaScript。JavaScript代码返回一个对象。
public Object execute(){
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine e = sem.getEngineByName("nashorn");  
        Invocable invocable = (Invocable)e;
        ScriptEngineFactory f = e.getFactory();
        Object result;
        try {
            String statement = "function fetch(value, count) { count++ ; return {'value': value,'count' : count} }; } ; ";
            CompiledScript cs = ((Compilable)e).compile(statement);
            cs.eval();
            result = invocable.invokeFunction("fetch", 10,2);

        }   
        catch (Exception se ) {
            String version = System.getProperty("java.version");
            System.out.println(version);
            result = "script exception ";
        }

我该如何在Java中访问我的结果对象中的对象值?最初,我尝试使用result.toString()来获取结果。似乎会返回[Object Object]

是否有一种方法,可以将结果返回到result对象中,以便我可以获得等效于Javascript中的result.valueresult.count的值。

2个回答

7

如果你的程序的返回值是一个JavaScript对象,你应该将其转换为Java中的jdk.nashorn.api.scripting.JSObject,然后使用它的方法(例如getMember())来查询和操作它。


4
您不应该从JavaScript函数中返回一个JSObject。正确的做法是:
{
  value: value,
  count : count
}

所以,您可以使用这个Java代码。
package de.lhorn.so;

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 jdk.nashorn.api.scripting.JSObject;

public class SOPlayground {

    public static void main(String[] args) throws Exception {
        SOPlayground sop = new SOPlayground();
        JSObject jso = sop.execute();
        System.out.println("value=" + jso.getMember("value"));
        System.out.println("count=" + jso.getMember("count"));
    }

    public JSObject 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(value, count) { count++ ; return {value: value, count : count} };";
        final CompiledScript compiled = compilable.compile(statement);

        compiled.eval();

        return (JSObject) invocable.invokeFunction("fetch", 10, 2);
    }
}

输出:

value=10
count=3.0

非常感谢!JSObject救了我的一天。在我的情况下,使用ScriptObjectMirror是完全不可取的。 - Rahul
@Rahul,JSObject 接口由 jdk.nashorn.api.scripting.ScriptObjectMirror 实现,该接口实际上是由 invokeFunction 返回的。 - Alnitak
我目前正在使用强制类型转换为Map<String, Object>,这很好用,因为ScriptObjectMirror实际上实现了该接口... 我应该改用JSObject吗?我还没有找到明确的文档... Invocable接口只定义了返回类型为Object,这相当无用。 - Stijn de Witt

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