Java詳解ScriptEngine接口動(dòng)態(tài)執(zhí)行JS腳本
大多的方法描述都來(lái)自于jdk11API幫助文檔,由于是機(jī)翻,可能有些難以理解,大家多多擔(dān)待
簡(jiǎn)介
首先來(lái)看一下JDK11API文檔中對(duì)ScriptEngine的描述
模塊 java.scripting
軟件包 javax.script
Interface ScriptEngin
public interface ScriptEngine
ScriptEngine是基本接口,其方法必須在本規(guī)范的每個(gè)實(shí)現(xiàn)中完全起作用。
這些方法提供基本腳本功能。 寫(xiě)入這個(gè)簡(jiǎn)單接口的應(yīng)用程序可以在每個(gè)實(shí)現(xiàn)中進(jìn)行最少的修改。 它包括執(zhí)行腳本的方法,以及設(shè)置和獲取值的方法。
值是兩種類(lèi)型的鍵/值對(duì)。 第一類(lèi)對(duì)包括其密鑰在本說(shuō)明書(shū)中保留和定義的那些或由各個(gè)實(shí)現(xiàn)組成。 具有保留鍵的對(duì)中的值具有指定的含義。
另一種類(lèi)型的對(duì)包括那些創(chuàng)建Java語(yǔ)言綁定的對(duì),這些值通常由腳本中的相應(yīng)鍵或它們的裝飾形式表示。
Eval(String script)
eval方法有多個(gè)重載,本文只介紹最常用的Eval(String script)
描述
執(zhí)行指定的腳本。
實(shí)例代碼
/** * ScriptEngine.eval() */ public void jsEngineEvalTest() { ScriptEngineManager sem = new ScriptEngineManager(); //查找并為給定的擴(kuò)展創(chuàng)建ScriptEngine。也可用getEngineByName,查找并為給定名稱(chēng)創(chuàng)建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(); } }
執(zhí)行的腳本很簡(jiǎn)單,遍歷輸出了一個(gè)數(shù)組
結(jié)果如下所示:
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) : 設(shè)置ScriptEngine狀態(tài)中的鍵/值對(duì),可以創(chuàng)建用于執(zhí)行腳本的Java語(yǔ)言綁定,也可以以其他方式使用,具體取決于是否保留鍵。
Object get?(String key) : 檢索在此引擎狀態(tài)下設(shè)置的值。 該值可能是其中之一是使用設(shè)置setValue或狀態(tài)的其他值ScriptEngine ,取決于實(shí)施。
實(shí)例代碼
/** * 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("被翻轉(zhuǎn)后的字符串:"+name); }
此處的js腳本是將str字符串進(jìn)行翻轉(zhuǎn)操作,結(jié)果如下
被翻轉(zhuǎn)后的字符串:tseTtuPenignEsj
CompiledScript
描述
通過(guò)存儲(chǔ)編譯結(jié)果的類(lèi)進(jìn)行擴(kuò)展。 狀態(tài)可以以Java類(lèi),Java類(lèi)文件或腳本語(yǔ)言操作碼的形式存儲(chǔ)。 腳本可以重復(fù)執(zhí)行而無(wú)需重新分析。
我的理解:將ScriptEngine解析一段腳本的結(jié)果存起來(lái),方便多次調(diào)用。但是使用時(shí)要先將ScriptEngine用Compilable接口強(qiáng)制轉(zhuǎn)換,然后調(diào)用compile(String script)方法就能返回一個(gè)CompiledScript對(duì)象,下次使用的時(shí)候調(diào)用一下CompiledScript.eval()即可,以此可以省略每次使用腳本都要重新解析一遍的過(guò)程。
實(shí)例代碼
/** * CompiledScript */ public void compiledScriptTest(){ ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("javascript"); //進(jìn)行強(qiáng)制轉(zhuǎn)換 Compilable compilable = (Compilable) engine; String script = "print('CompiledScriptTest')"; try { //腳本解析結(jié)果存到JSFunction中,下次使用時(shí)用jsFunction.eval()即可 CompiledScript jsFunction = compilable.compile(script); jsFunction.eval(); } catch (ScriptException e) { e.printStackTrace(); } }
此處js腳本只是進(jìn)行一個(gè)簡(jiǎn)單的輸出,結(jié)果如下:
CompiledScriptTest
Bindings
描述
沒(méi)有找到對(duì)Bindings很準(zhǔn)確的解釋?zhuān)@里寫(xiě)下查閱了很多碼友的筆記后我的得出的結(jié)論,Bindings是一個(gè)用來(lái)存放數(shù)據(jù)的容器,它有3個(gè)層級(jí),為Global級(jí)、Engine級(jí)和Local級(jí),前2者通過(guò)ScriptEngine.getBindings()獲得,是唯一的對(duì)象,而Local Binding由ScriptEngine.createBindings()獲得,很好理解,每次都產(chǎn)生一個(gè)新的。Global對(duì)應(yīng)到工廠,Engine對(duì)應(yīng)到ScriptEngine,向這2者里面加入任何數(shù)據(jù)或者編譯后的腳本執(zhí)行對(duì)象,在每一份新生成的Local Binding里面都會(huì)存在。
實(shí)例代碼
/** * 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中傳入鍵值對(duì) bindings.put("a", 1); bindings.put("b", 2); //調(diào)用eval時(shí)將bindings也傳入 Object result = JSFunction.eval(bindings); System.out.println(result); } catch (ScriptException e) { e.printStackTrace(); } }
此處腳本代碼進(jìn)行了一個(gè)簡(jiǎn)單的加法運(yùn)算,結(jié)果如下:
3.0
到此這篇關(guān)于Java詳解ScriptEngine接口動(dòng)態(tài)執(zhí)行JS腳本的文章就介紹到這了,更多相關(guān)Java ScriptEngine內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring JDBCTemplate原理及使用實(shí)例
這篇文章主要介紹了Spring JDBCTemplate原理及使用實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Spring Boot和Vue跨域請(qǐng)求問(wèn)題原理解析
這篇文章主要介紹了Spring Boot和Vue跨域請(qǐng)求問(wèn)題原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12詳解MyBatis的動(dòng)態(tài)SQL實(shí)現(xiàn)原理
MyBatis提供了強(qiáng)大的動(dòng)態(tài)SQL語(yǔ)句生成功能,以應(yīng)對(duì)復(fù)雜的業(yè)務(wù)場(chǎng)景,本篇文章將結(jié)合MyBatis解析SQL語(yǔ)句的過(guò)程對(duì)MyBatis中對(duì)<if>,<where>,<foreach>等動(dòng)態(tài)SQL標(biāo)簽的支持進(jìn)行分析,需要的朋友可以參考下2023-07-07springboot整合mybatis-plus代碼生成器的配置解析
這篇文章主要介紹了springboot整合mybatis-plus代碼生成器的配置解析,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02Spring?@Cacheable注解類(lèi)內(nèi)部調(diào)用失效的解決方案
這篇文章主要介紹了Spring?@Cacheable注解類(lèi)內(nèi)部調(diào)用失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01