Sök…


Introduktion

Java i sig är ett extremt kraftfullt språk, men dess kraft kan ytterligare utvidgas Tack vare att JSR223 (Java Specification Request 223) introducerade en skriptmotor

Anmärkningar

Java Scripting API gör det möjligt för externa skript att interagera med Java

Scripting API kan aktivera interaktion mellan skriptet och java. Skriptspråken måste ha en implementering av Script Engine på klassvägen.

Som standard tillhandahålls JavaScript (även känt som ECMAScript) av nashorn som standard. Varje skriptmotor har ett skriptkontext där alla variabler, funktioner, metoder lagras i bindningar. Ibland kanske du vill använda flera sammanhang eftersom de stödjer omdirigering av utdata till en buffrad Writer och fel till en annan.

Det finns många andra manusbibliotek som Jython och JRuby. Så länge de är på klassvägen kan du utvärdera kod.

Vi kan använda bindningar för att exponera variabler i skriptet. Vi behöver flera bindningar i vissa fall eftersom exponering av variabler för motorn i princip är att exponera variabler för endast den motorn, ibland måste vi exponera vissa variabler som systemmiljö och väg som är densamma för alla motorer av samma typ. I så fall kräver vi en bindning som är en global räckvidd. Att exponera variabler för det exponerar det för alla skriptmotorer som skapats av samma EngineFactory

Utvärdering av en javascript-fil i -scripting-läge för 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;
    }
    
}

Nu huvudmetoden

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

Din produktion bör vara lik den här
hello world

Som du ser har den exponerade variabeln x skrivits ut. Testa nu med en fil.

Här har vi test.js

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

Och den uppdaterade huvudmetoden

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

Antagande att test.js finns i samma katalog som din applikation. Du borde ha output som liknar detta

hello world
hello test.js:test


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow