2014-04-15 5 views
5

Ich habe folgendes Programm, das Javascript in Java (nashorn) ausführt. Der Javascript-Code gibt ein Objekt zurück.Wie entpacken Sie die Werte von Javascript (Nashorn) in Java-Objekt zurückgegeben?

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 "; 
     } 

Wie kann ich auf die Objektwerte in meinem Ergebnisobjekt in Java zugreifen? Zunächst versuchte ich, result.toString() zu verwenden, um Ergebnisse zu erhalten. Scheint return [Object Object]

Gibt es eine Möglichkeit, wo ich die Ergebnisse zu result Objekt zurückkehren konnte, so dass ich zu result.value äquivalente Werte bekommen konnte, und result.count (ähnlich wie Javascript).

Antwort

3

Sie geben keine JSObject von der JavaScript-Funktion zurück. Gültig wäre

{ 
    value: value, 
    count : count 
} 

So könnten Sie diesen Java-Code verwenden.

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); 
    } 
} 

Ausgang:

value=10 
count=3.0 
+0

Vielen Dank! JSObject hat meinen Tag gerettet. Ich habe ScriptObjectMirror benutzt, was in meinem Fall kein Nein ist. – Rahul

+0

@Rahul Die Schnittstelle von Yahoo 'JSObject' wird durch den' jdk.nashorn.api.scripting.ScriptObjectMirror' implementiert, der tatsächlich von 'invokeFunction' zurückgegeben wird. – Alnitak

+0

Ich verwende derzeit eine Umwandlung zu 'Map ', was gut funktioniert, da 'ScriptObjectMirror' diese Schnittstelle tatsächlich implementiert ... Soll ich stattdessen 'JSObject' verwenden? Ich habe dazu noch keine klare Dokumentation gefunden ... Die 'Invocable'-Schnittstelle definiert nur' Object' als Rückgabetyp, was ziemlich nutzlos ist. –

6

Wenn der Rückgabewert Ihres Programms ein JavaScript-Objekt ist, sollten Sie es in jdk.nashorn.api.scripting.JSObject in Java umwandeln und dann seine Methoden (z. B. getMember()) verwenden, um es abzufragen und zu manipulieren.