JDK中內嵌JS引擎介紹及使用

来源:https://www.cnblogs.com/stars-one/archive/2022/12/04/16950837.html
-Advertisement-
Play Games

原文: JDK中內嵌JS引擎介紹及使用 - Stars-One的雜貨小窩 最近研究閱讀這個APP,其主要功能就是通過一個個書源,從而實現移動端閱讀的體驗 比如說某些線上小說閱讀網站,會加上相應的廣告,從而影響用戶閱讀體驗,於是閱讀這個APP就是做了類似凈化閱讀體驗 但是小說閱讀網站千千萬萬,如果去適 ...


原文: JDK中內嵌JS引擎介紹及使用 - Stars-One的雜貨小窩

最近研究閱讀這個APP,其主要功能就是通過一個個書源,從而實現移動端閱讀的體驗

比如說某些線上小說閱讀網站,會加上相應的廣告,從而影響用戶閱讀體驗,於是閱讀這個APP就是做了類似凈化閱讀體驗

但是小說閱讀網站千千萬萬,如果去適配每個小說閱讀網站,豈不是累死,且作者也會有被髮律師函的危險,於是作者提供了對應的工具,允許各位用戶可自定義書源,閱讀APP則通過導入書源,即可實現對某個小說閱讀網站的支持

這裡說的書源,實際上就是JS腳本代碼,作者本質上是使用了rhino這個Java的JS引擎技術來實現的

介紹

JDK1.6和JDK1.7採用Rhino。Nashorn 支持 ECMAScript 5.1 規範,使用基於 JSR 292 的新語言特性,其中包含在 JDK 7 中引入的 invokedynamic,將 JavaScript 編譯成 Java 位元組碼。

從JDK1.8開始,Java採用Nashorn作為嵌入式 JavaScript 引擎。

本質上,都是通用標準ECMAScriptJS規範,沒啥過多的區別

JDK內置的方式,其實也就是將對應JS引擎的jar包一起集成在Java環境里了,如果想使用新版本的JS引擎,可以去對應的JS引擎上找最新版本的jar包或通過maven來引用依賴即可

rhino目前是由火狐瀏覽器團隊開發的,使用Java寫的一個JS引擎,目前也是在更新,如果想要更新,而不想更新JDK的話,可以直接使用maven引入最新的jar包即可

Nashorn之前是oracle團隊在開發,現在看github的話,是有openjdk團隊在維護

而在Android平臺方面,由於平臺對JVM進行了調整,所以預設是不支持的,但是好消息的是,有大神將移植到了Android平臺上,具體可以查看APISENSE/rhino-android,需要的話可以直接引入依賴即可

不過作者寫的使用文檔不太清晰,這裡我比較推薦使用閱讀APP開發者的gedoor/rhino-android,實際上也是基於APISENSE/rhino-android進行了一定的調整,使用起來和Java內置的步驟是一樣的

可能有同學就有疑惑了,使用這個JS引擎能有什麼作用呢?

這裡就舉個例子,有個加密方法,是通過js去實現的,但是現在如果讓我們想要獲取到加密的結果,得通過閱讀JS源碼,看懂加密思路後再使用Java代碼重現實現,是不是十分的複雜?

但如果採用JS引擎,我們只需要將對應的JS方法代碼拿到,之後我們只需要傳參數,通過JS引擎執行加密過程,即可得到加密後的參數了

PS: 最後,註意一下,上述說到的兩種JS引擎,只支持部分ES6特性,所有,如果你的JS代碼有ES6特性的,可能執行的時候會報錯!

下文以JDK8內置的JS引擎為例,講解一下使用

使用

1.基本使用

首先,我們需要通過ScriptEngineManager對象獲取JS腳本引擎engine對象,之後通過engine.eval()方法來執行我們需要的js代碼

// 1、獲得腳本引擎對象,選擇腳本語言
val manager = ScriptEngineManager()
// 亦可以是js縮寫,代表JavaScript腳本語言
val engine = manager.getEngineByName("js")
val result = engine.eval("""
    var num  = 5+2;
    num
""".trimIndent())
println(result)

PS: 如果是gedoor/rhino-android,getEngineByName()方法裡面傳rhino這個字元串!

2.獲取JS變數數值

比較多的情況就是,我們需要通過JS去執行邏輯,之後得到返回的結果,有以下2種方式獲取數值

  1. 通過eval()方法的返回值(如上面基本使用的示例代碼),可以理解為在瀏覽器的控制台執行js代碼後的控制台會輸出的數值
  2. 通過作用域變數

作用域變數的方式代碼如下:

// 1、獲得腳本引擎對象,選擇腳本語言
val manager = ScriptEngineManager()
// 亦可以是js縮寫,代表JavaScript腳本語言
val engine = manager.getEngineByName("js")
//聲明一個變數
engine.put("finalResult","")

//註冊一個js方法
engine.eval("""
    function add(a,b){
        return a + b 
    }
""".trimIndent())

//執行獲取結果,賦予finalResult數據
engine.eval("finalResult = add(2,3)")
println(engine["finalResult"])

或者直接在js中聲明變數finalResult,如下代碼:

// 1、獲得腳本引擎對象,選擇腳本語言
val manager = ScriptEngineManager()
// 亦可以是js縮寫,代表JavaScript腳本語言
val engine = manager.getEngineByName("js")

//註冊一個js方法
engine.eval("""
    function add(a,b){
        return a + b 
    }
""".trimIndent())

//執行獲取結果
engine.eval("var finalResult = add(2,3)")
println(engine["finalResult"])

3.JS使用Java類型數值

// 1、獲得腳本引擎對象,選擇腳本語言
val manager = ScriptEngineManager()
// 亦可以是js縮寫,代表JavaScript腳本語言
val engine = manager.getEngineByName("js")
val file = File("D:\\temp\\qrcode.gif")
//將文件的對象設置為JS變數
engine.put("myFile",file)

//註冊一個js方法
engine.eval("""
    print(myFile.getPath());
""".trimIndent())

上面js中的print實際上也是Java提供的方法,而myFile則是我們Java中的一個File對象,JS代碼中可以使用這個對象及相應的Java方法

參考


提問之前,請先看提問須知 點擊右側圖標發起提問 聯繫我 或者加入QQ群一起學習 Stars-One安卓學習交流群 TornadoFx學習交流群:1071184701
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JQuery04 6.jQuery的DOM操作02 6.9常用遍歷節點方法 取得匹配元素的所有子元素組成的集合:children(),該方法只考慮子元素而不考慮任何後代元素 取得匹配元素後面的同輩元素的集合:next()/nextAll() 如果是next方法,就是拿到指定元素後面的一個元素,如果是 ...
  • 在 javascript 中內置了一個 Date 對象,可用於實現一些日期和時間的操作。 本文整理 js 日期對象的詳細功能,使用 js 日期對象獲取具體日期、昨天、今天、明天、每月天數、時間戳等,以及常用的日期時間處理方法。 ...
  • 在如今,很多網頁已經可以手動切換明亮模式和黑暗模式,網頁的主題切換已經成為了一個常用的需求,因此,本文將從常見框架的處理方式總結一些相關的操作,並探究其本質。 ...
  • Nginx (Engine X)是一個輕量級的Web伺服器 、反向代理伺服器及電子郵件(IMAP/POP3)代理伺服器、高性能的HTTP伺服器,它以高穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名。 ...
  • 如果你接手了別人的代碼工程,卻發現對方使用的 python 版本或者依賴庫都和你的環境不相容時,怎麼辦?打算卸掉自己原來的那一套環境再重來嗎?真麻煩! ...
  • 該筆記整理至尚矽谷周陽老師的SpringCloud課程SpringCloud Alibaba篇 SpringCloud Alibaba入門簡介 Spring Cloud Netflix 項目進入維護模式,Spring Cloud Netflix 將不再開發新的組件。Spring Cloud 版本迭代 ...
  • ###Http Http (超文本輸出協議) 是一種分散式、協作式和超媒體信息系統的應用層協議,它通常運行在TCP之上,網際網路應用最廣泛的便是Http協議,所有www都遵循這個標準。主要用於Web 瀏覽器與 Web 伺服器之間的通信而設計的,但也可以用於其他目的,是一個基於 TCP/IP 通信協議來 ...
  • 隨著跨境獨立站的流行,中英雙語的公司官網越來越受到重視。 此項目是基於開源CMS開發出的中英文雙語外貿企業網站內容管理系統,命名HanCMS HanCMS 漢CMS中英雙語多語種外貿網站系統,是一個輕量級的網站系統,訪問速度極快,使用簡單。程式代碼簡潔嚴謹,完全免費開源。可用於建設各種類型的中英文網 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...