Java Language
Использование других языков сценариев в Java
Поиск…
Вступление
Java сама по себе является чрезвычайно мощным языком, но ее мощность может быть расширена благодаря JSR223 (Java Specification Request 223), представляющему механизм сценария
замечания
API Java Scripting позволяет внешним скриптам взаимодействовать с Java
API-интерфейс Scripting API позволяет взаимодействовать между скриптом и java. Языки сценариев должны иметь реализацию Script Engine на пути к классам.
По умолчанию JavaScript (также известный как ECMAScript) предоставляется по умолчанию по умолчанию. Каждый скриптовый движок имеет контекст сценария, в котором все переменные, функции, методы хранятся в привязках. Иногда вы можете использовать несколько контекстов, поскольку они поддерживают перенаправление вывода на буферный Writer и ошибку на другую.
Есть много других библиотек сценариев, таких как Jython и JRuby. Пока они находятся на пути к классу, вы можете использовать код eval.
Мы можем использовать привязки для отображения переменных в скрипте. В некоторых случаях нам нужно несколько привязок, поскольку подверженность переменных движку в основном заключается в том, чтобы подвергать переменные только этому движку, иногда нам нужно выставлять определенные переменные, такие как системная среда и путь, одинаковый для всех двигателей того же типа. В этом случае нам требуется привязка, которая является глобальной областью. Отображение переменных, которые выставляют его всем движкам сценариев, созданным тем же EngineFactory
Оценка файла javascript в режиме -scripting 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;
}
}
Теперь основной метод
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);");
}
Ваш результат должен быть похож на этот
hello world
Как вы видите, открытая переменная x была напечатана. Теперь тестирование с помощью файла.
Здесь у нас есть test.js
print(x);
function test(){
print("hello test.js:test");
}
test();
И обновленный основной метод
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");
}
Предполагая, что test.js находится в том же каталоге, что и ваше приложение, вы должны иметь аналогичный результат
hello world
hello test.js:test