6 votes

Java : Retourner un objet à partir de ScriptEngine javascript

J'essaie d'évaluer le javascript en Java en utilisant la fonction ScriptEngine classe. Voici un petit exemple de ce que j'essaie de faire :

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

public class Test {
    public static void main(String[] args) {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("js"); //Creates a ScriptEngine
        Object obj = engine.eval("var obj = { value: 1 }; return obj; "); // Evals the creation of a simple object
        System.out.println(obj.value); // I get an invalid token error when trying to print a property of the object
    }
}

Je suis presque sûr que ce devrait mais je suis perplexe, et je prendrai toute l'aide que je peux avoir.

7voto

Andreas Points 3334

Remarque : ce qui suit est valable pour Java 8, en utilisant l'option Nashorn moteur.

Tout d'abord, pour que le code se compile, supprimez l'option .value de la println() déclaration. obj est déclaré comme étant de type Object y Object n'a pas de value champ.

Une fois que vous avez fait cela, vous obtenez l'exception suivante en exécutant le code :

Exception in thread "main" javax.script.ScriptException: <eval>:1:25 Invalid return statement
var obj = { value: 1 };  return obj; 
                         ^ in <eval> at line number 1 at column number 25

C'est parce que vous n'avez pas de fonction, donc vous ne pouvez pas appeler return . La valeur de retour du script est la valeur de la dernière expression, donc il suffit de dire obj .

Maintenant, il va s'exécuter et imprimer [object Object] . Pour voir quel type d'objet vous avez récupéré, changez en println(obj.getClass().getName()) . Cela imprimera jdk.nashorn.api.scripting.ScriptObjectMirror . J'ai mis un lien vers la javadoc pour vous faciliter la tâche.

ScriptObjectMirror met en œuvre Bindings qui à son tour met en œuvre Map<String, Object> Vous pouvez donc appeler get("value") .

Le code de travail est :

import javax.script.*;

public class Test {
    public static void main(String[] args) throws ScriptException {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
        Bindings obj = (Bindings)engine.eval("var obj = { value: 1 };  obj; ");
        Integer value = (Integer)obj.get("value");
        System.out.println(value); // prints: 1
    }
}

UPDATE

Le but était de créer un objet avec des fonctions, est-ce possible avec ce moteur ? Il n'y a pas d'objet Function.

Exemple pour savoir comment faire :

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import jdk.nashorn.api.scripting.ScriptObjectMirror;

public class Test {
    public static void main(String[] args) throws Exception {
        String script = "var f = {\n" +
                        "  value: 0,\n" +
                        "  add: function(n) {\n" +
                        "    this.value += n;\n" +
                        "    return this.value;\n" +
                        "  }\n" +
                        "};\n" +
                        "f; // return object to Java\n";
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
        ScriptObjectMirror obj = (ScriptObjectMirror)engine.eval(script);
        System.out.println("obj.value = " + obj.getMember("value"));
        System.out.println("obj.add(5): " + obj.callMember("add", 5));
        System.out.println("obj.add(-3): " + obj.callMember("add", -3));
        System.out.println("obj.value = " + obj.getMember("value"));
    }
}

SORTIE

obj.value = 0
obj.add(5): 5.0
obj.add(-3): 2.0
obj.value = 2.0

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X