2014-04-15 11 views
5

Ho il seguente programma, che esegue Javascript in Java (nashorn). Il codice Javascript sta restituendo un oggetto.Come cancellare i valori restituiti da javascript (nashorn) nell'oggetto Java?

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

Come accedere ai valori dell'oggetto nel mio oggetto risultato in Java? Inizialmente, ho provato a utilizzare result.toString() per ottenere risultati. Sembra return [Object Object]

C'è un modo, dove ho potuto restituire i risultati per result oggetto così che avrei potuto ottenere valori equivalenti a result.value, e result.count (simile a Javascript).

risposta

3

Non si restituisce un JSObject dalla funzione JavaScript. Valido sarebbe

{ 
    value: value, 
    count : count 
} 

Quindi è possibile utilizzare questo codice 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); 
    } 
} 

uscita:

value=10 
count=3.0 
+0

Grazie mille! JSObject mi ha salvato la giornata. Stavo usando ScriptObjectMirror che è un no totale nel mio caso. – Rahul

+0

@Rahul L'interfaccia Nahorn 'JSObject' è implementata da' jdk.nashorn.api.scripting.ScriptObjectMirror' effettivamente restituito da 'invokeFunction'. – Alnitak

+0

Attualmente sto usando un cast per 'Map ', che funziona bene perché 'ScriptObjectMirror' implementa effettivamente quell'interfaccia ... Dovrei usare' JSObject' invece? Non ho ancora trovato una documentazione chiara su questo argomento ... L'interfaccia 'Invocable' definisce appena' Object' come tipo restituito, che è piuttosto inutile. –

6

Se il valore di ritorno del programma è un oggetto JavaScript, dovresti poterlo trasmettere a jdk.nashorn.api.scripting.JSObject in Java e quindi utilizzarne i metodi (ad esempio getMember()) per interrogarlo e manipolarlo.

Problemi correlati