Recherche…


Introduction

Java en soi est un langage extrêmement puissant, mais sa puissance peut encore être étendue Grâce à JSR223 (Java Specification Request 223), qui introduit un moteur de script

Remarques

L'API de script Java permet aux scripts externes d'interagir avec Java

L'API de script peut permettre une interaction entre le script et Java. Les langages de script doivent avoir une implémentation de Script Engine sur le classpath.

Par défaut, JavaScript (également appelé ECMAScript) est fourni par nashorn par défaut. Chaque moteur de script a un contexte de script où toutes les variables, fonctions et méthodes sont stockées dans des liaisons. Parfois, vous pouvez utiliser plusieurs contextes car ils prennent en charge la redirection de la sortie vers un enregistreur en mémoire tampon et une erreur vers une autre.

Il existe de nombreuses autres bibliothèques de moteur de script comme Jython et JRuby. Tant qu'ils sont sur le classpath, vous pouvez évaluer le code.

Nous pouvons utiliser des liaisons pour exposer des variables dans le script. Dans certains cas, nous avons besoin de plusieurs liaisons, car l'exposition des variables au moteur consiste essentiellement à exposer les variables uniquement à ce moteur. Parfois, nous devons exposer certaines variables comme l'environnement système et le chemin d'accès pour tous les moteurs du même type. Dans ce cas, nous avons besoin d'une liaison de portée globale. Exposition de variables à ceux qui l'exposent à tous les moteurs de script créés par le même EngineFactory

Évaluation d'un fichier javascript en mode script de nashorn

public class JSEngine {
    
    /*
    * Note Nashorn is only available for Java-8 onwards
    * You can use rhino from ScriptEngineManager.getEngineByName("js");
    */
    
    ScriptEngine engine;
    ScriptContext context;
    public Bindings scope;
    
    // Initialize the Engine from its factory in scripting mode
    public JSEngine(){
        engine = new NashornScriptEngineFactory().getScriptEngine("-scripting");
        // Script context is an interface so we need an implementation of it
        context = new SimpleScriptContext();
        // Create bindings to expose variables into
        scope = engine.createBindings();
    }
    
    // Clear the bindings to remove the previous variables
    public void newBatch(){
        scope.clear();
    }
    
    public void execute(String file){
        try {
            // Get a buffered reader for input
            BufferedReader br = new BufferedReader(new FileReader(file));
            // Evaluate code, with input as bufferdReader
            engine.eval(br);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(JSEngine.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ScriptException ex) {
            // Script Exception is basically when there is an error in script
            Logger.getLogger(JSEngine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void eval(String code){
        try {
            // Engine.eval basically treats any string as a line of code and evaluates it, executes it
            engine.eval(code);
        } catch (ScriptException ex) {
            // Script Exception is basically when there is an error in script
            Logger.getLogger(JSEngine.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    // Apply the bindings to the context and set the engine's default context
    public void startBatch(int SCP){
        context.setBindings(scope, SCP);
        engine.setContext(context);
    }
    
    // We use the invocable interface to access methods from the script
    // Invocable is an optional interface, please check if your engine implements it
    public Invocable invocable(){
        return (Invocable)engine;
    }
    
}

Maintenant la méthode principale

public static void main(String[] args) {
    JSEngine jse = new JSEngine();
    // Create a new batch probably unecessary
    jse.newBatch();
    // Expose variable x into script with value of hello world
    jse.scope.put("x", "hello world");
    // Apply the bindings and start the batch
    jse.startBatch(ScriptContext.ENGINE_SCOPE);
    // Evaluate the code
    jse.eval("print(x);");
}

Votre sortie devrait être similaire à celle-ci
hello world

Comme vous pouvez le voir, la variable exposée x a été imprimée. Maintenant, testez avec un fichier.

Ici nous avons test.js

print(x);
function test(){
    print("hello test.js:test");
}
test();

Et la méthode principale mise à jour

public static void main(String[] args) {
    JSEngine jse = new JSEngine();
    // Create a new batch probably unecessary
    jse.newBatch();
    // Expose variable x into script with value of hello world
    jse.scope.put("x", "hello world");
    // Apply the bindings and start the batch
    jse.startBatch(ScriptContext.ENGINE_SCOPE);
    // Evaluate the code
    jse.execute("./test.js");
}

En supposant que test.js se trouve dans le même répertoire que votre application Vous devriez avoir une sortie similaire à celle-ci

hello world
hello test.js:test


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow