首頁 > 軟體

Java詳解ScriptEngine介面動態執行JS指令碼

2022-08-08 14:00:39

大多的方法描述都來自於jdk11API幫助檔案,由於是機翻,可能有些難以理解,大家多多擔待

簡介

首先來看一下JDK11API檔案中對ScriptEngine的描述

模組 java.scripting

軟體包 javax.script

Interface ScriptEngin

public interface ScriptEngine

ScriptEngine是基本介面,其方法必須在本規範的每個實現中完全起作用。

這些方法提供基本指令碼功能。 寫入這個簡單介面的應用程式可以在每個實現中進行最少的修改。 它包括執行指令碼的方法,以及設定和獲取值的方法。

值是兩種型別的鍵/值對。 第一類對包括其金鑰在本說明書中保留和定義的那些或由各個實現組成。 具有保留鍵的對中的值具有指定的含義。

另一種型別的對包括那些建立Java語言繫結的對,這些值通常由指令碼中的相應鍵或它們的裝飾形式表示。

Eval(String script)

eval方法有多個過載,本文只介紹最常用的Eval(String script)

描述

執行指定的指令碼。

範例程式碼

    /**
     * ScriptEngine.eval()
     */
    public void jsEngineEvalTest() {
        ScriptEngineManager sem = new ScriptEngineManager();
        //查詢併為給定的擴充套件建立ScriptEngine。也可用getEngineByName,查詢併為給定名稱建立ScriptEngine 
        ScriptEngine jsEngine = sem.getEngineByExtension("js");
        try {
            jsEngine.eval("var array = [1, 2, 3, 4, 5];for (var i = 0; i < array.length; i++) {print('index:' + i + ',value:' + array[i]);}");
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

執行的指令碼很簡單,遍歷輸出了一個陣列

結果如下所示:

index:0,value:1
index:1,value:2
index:2,value:3
index:3,value:4
index:4,value:5

Put() and Get()

描述

void put​(String key, Object value) : 設定ScriptEngine狀態中的鍵/值對,可以建立用於執行指令碼的Java語言繫結,也可以以其他方式使用,具體取決於是否保留鍵。

Object get​(String key) : 檢索在此引擎狀態下設定的值。 該值可能是其中之一是使用設定setValue或狀態的其他值ScriptEngine ,取決於實施。

範例程式碼

    /**
     * ScriptEngine.put() and ScriptEngine.get()
     */
    public void jsEnginePutTest(){
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");
        //向engine中存值
        engine.put("str", "jsEnginePutTest");
        try {
            engine.eval("var output ='' ;for (i = 0; i <= str.length; i++) {  output = str.charAt(i) + output }");
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        //從engine中取值
        String name = (String) engine.get("output");
        System.out.println("被翻轉後的字串:"+name);
    }

此處的js指令碼是將str字串進行翻轉操作,結果如下

被翻轉後的字串:tseTtuPenignEsj

CompiledScript

描述

通過儲存編譯結果的類進行擴充套件。 狀態可以以Java類,Java類檔案或指令碼語言操作碼的形式儲存。 指令碼可以重複執行而無需重新分析。

我的理解:將ScriptEngine解析一段指令碼的結果存起來,方便多次呼叫。但是使用時要先將ScriptEngine用Compilable介面強制轉換,然後呼叫compile(String script)方法就能返回一個CompiledScript物件,下次使用的時候呼叫一下CompiledScript.eval()即可,以此可以省略每次使用指令碼都要重新解析一遍的過程。

範例程式碼

    /**
     * CompiledScript
     */
    public void compiledScriptTest(){
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("javascript");
        //進行強制轉換
        Compilable compilable = (Compilable) engine;
        String script = "print('CompiledScriptTest')";
        try {
        	//指令碼解析結果存到JSFunction中,下次使用時用jsFunction.eval()即可
            CompiledScript jsFunction = compilable.compile(script);
            jsFunction.eval();
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

此處js指令碼只是進行一個簡單的輸出,結果如下:

CompiledScriptTest

Bindings

描述

沒有找到對Bindings很準確的解釋,這裡寫下查閱了很多碼友的筆記後我的得出的結論,Bindings是一個用來存放資料的容器,它有3個層級,為Global級、Engine級和Local級,前2者通過ScriptEngine.getBindings()獲得,是唯一的物件,而Local Binding由ScriptEngine.createBindings()獲得,很好理解,每次都產生一個新的。Global對應到工廠,Engine對應到ScriptEngine,向這2者裡面加入任何資料或者編譯後的指令碼執行物件,在每一份新生成的Local Binding裡面都會存在。

範例程式碼

    /**
     * Bindings
     */
    public void jsEngineBindingsTest(){
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
        Compilable compilable = (Compilable) engine;
        Bindings bindings = engine.createBindings();
        String script = "function add(num1,num2){return num1+num2} add(a, b)";
        CompiledScript JSFunction = null;
        try {
            JSFunction = compilable.compile(script);
            //向bingdings中傳入鍵值對
            bindings.put("a", 1);
            bindings.put("b", 2);
            //呼叫eval時將bindings也傳入
            Object result = JSFunction.eval(bindings);
            System.out.println(result);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

此處指令碼程式碼進行了一個簡單的加法運算,結果如下:

3.0

到此這篇關於Java詳解ScriptEngine介面動態執行JS指令碼的文章就介紹到這了,更多相關Java ScriptEngine內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com