簡體   English   中英

將 Javascript 屬性連接到 Java 對象

[英]Connecting Javascript properties to Java object

問題

我正在嘗試將一個 Java 對象提供給一個腳本,該腳本通常會在網頁的文檔對象模型 (DOM) 上運行。 在大多數情況下,此功能按預期運行。 但是,我在處理 DOM 元素的屬性/屬性時遇到了問題。

一個特定的屬性鏈是somediv.firstChild.href 我想不通的是如何動態獲取firstChild屬性值。 目前我能想到的最簡單的方法是使用source.replaceAll("firstChild", "firstChild()"); 強制firstChild屬性調用函數firstChild()代替。 然而,這最終會打開一個新的蠕蟲罐頭。

問題

如何定義可以傳遞給可以通過 DOM 操作的 javascript 函數的對象?

背景

從 C# 中學習

在深入研究 Java 之前,我學習了 C#。 在 C# 中,setter 和 getter 的概念非常普遍。 如果這個接口方法在 Java 中可用,我的問題就會解決。

public string firstChild {
    get { return this.getFirstChild(); }
    set { this.setFirstChild(value); }
}

當前實施

劇本是由目前在功能,我可以在通過包裝它調用windowdocument Java對象到函數的工作空間。

documentSpoofedDomElement的特殊頂級版本(擴展它),但在功能上與下面顯示的示例相同。 window是另一個具有處理事件偵聽器的最少函數的對象。

用於操作 DOM 的 Javascript(代碼段)

var somediv = document.createElement('div');
somediv.style.display = "block"
somediv.innerHTML="<a href='/mywork/server/test.html'>The Test Server Homepage</a>";
var linkvalue = somediv.firstChild.href;

此代碼段存儲為字符串theOriginalSource並在下一節中使用。

用於評估 Javascript 的 Java 代碼

String wrappedSource = "var scriptToInvoke = function(window, document){"
    + "\n" + theOriginalSource // from above
    + "\n};"

Object result = invocable.invokeFunction("scriptToInvoke", window, document);

此代碼段包裝了 javascript 代碼段,以便我可以傳入對象以用作windowdocument

欺騙 DOM 元素的 Java 類

public class SpoofedDomElement {
    public SpoofedDomElement firstChild;
    public String id;
    public String innerHtml;
    public String href;
    public SpoofedStyleProperties style = new SpoofedStyleProperties();
    public String tagname;
    ...
}

public class SpoofedStyleProperties {
    public String background = "transparent none repeat scroll 0% 0% auto padding-box border-box";
    public String color = null;
    public String display = "inline";
}

上面的類可以很好地處理代碼中不相關的部分(例如賦值somediv.style.display = "block" )。 但是當處理firstChildinnerHtml的值時,當任何一個值發生變化時,它就會開始崩潰。

過去的工作

注意,我在我所有的問題中都包含了這一部分,以記錄我為未來通過 Google 到達這里的 SO 用戶所做的嘗試。 這可能會通過幫助頭腦風暴來幫助某人找到解決方案。

嘗試的解決方案

我曾嘗試使用框架 ( HtmlUnit ) 來評估 Javascript。 但我無法控制執行了哪些 Javascript 片段。

潛在的解決方案

以下是我目前正在研究以找到解決方案的問題。 如果我發現了什么,我會回來報告的。

  • 有沒有辦法在 Java 中模擬 C# getter/setter 行為?
  • Javascript 可以將firstChild評估為函數嗎?
  • 有沒有辦法在 Javascript 中創建一個帶有 getter/setter 的包裝器,它可以調用我的 Java 類的函數?
  • 是否有一個用於 Nashorn(或類似)的 Apache Commons 庫不像完整的模擬框架(例如Selenium )那么重?

看來您正在嘗試從 Java 代碼實現對腳本對象的友好訪問,並試圖在 java 庫/庫之上提供腳本友好的 API。

第一部分 [從 Java 訪問腳本對象]

除了 javax.script.Invocable 接口,您還可以使用 JSObject。 Nashorn 將腳本對象公開為 jdk.nashorn.api.scripting.JSObject/.ScriptObjectMirror 的實例

https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/jdk/nashorn/api/scripting/ScriptObjectMirror.html

對於第二部分 [從腳本更友好地訪問 Java 對象]

您可以使用“JSAdapter”在腳本本身中編寫腳本友好的包裝器。

文檔和示例:

https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-JSAdapterconstructor

如果你更喜歡用 Java 做,你可以實現你自己的 jdk.nashorn.api.scripting.JSObject/.AbstractJSObject。

文檔和示例:

https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-jsobject

其他 nashorn 特定的腳本擴展也可用於在每個對象的基礎上捕獲未知的屬性/方法訪問:

任何腳本對象中的noSuchProperty掛鈎:

https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions- noSuchProperty

任何腳本對象中的noSuchMethod鈎子:

https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions- noSuchMethod

Object.bindProperties:

腳本 API 擴展可用於將一個對象的屬性綁定到另一個對象 - 源對象也可以是 Java 對象。

https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-Object.bindProperties

使用 jdk9,Dynalink API [ http://openjdk.java.net/jeps/276 ] 可以實現更靈活的語言間鏈接

也可以看看:

https://blogs.oracle.com/sundararajan/entry/dynamic_linker_api_for_the

https://blogs.oracle.com/sundararajan/entry/writing_pluggable_dynalink_linker_and

https://blogs.oracle.com/sundararajan/entry/nashorn_javascript_access_to_python

Nashorn OpenJDK 存儲庫的 dynalink 示例“samples/dynalink”目錄中有:

http://hg.openjdk.java.net/jdk9/dev/nashorn/file/4a6ee1185fc8/samples/dynalink

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM