Java Language
Använda andra skriptspråk i Java
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