Поиск…


Вступление

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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow