我正在尝试将Java对象提供给通常在网页的文档对象模型(DOM)上运行的脚本。在大多数情况下,这可以按预期运行。但是,在处理DOM元素的属性/属性时遇到了问题。
感兴趣的特定属性链是somediv.firstChild.href
。我无法弄清楚如何动态获取firstChild
属性值。我现在能想到的最简单的方法是使用source.replaceAll("firstChild", "firstChild()");
强制firstChild
属性来调用函数firstChild()
。然而,这最终会开辟出新的蠕虫病毒。
如何定义一个可以传递给可以通过DOM操作的javascript函数的对象?
在深入研究Java之前,我学会了C#。在C#中,setter和getter的概念非常普遍。如果这个接口方法在Java中可用,我的问题就会解决。
public string firstChild {
get { return this.getFirstChild(); }
set { this.setFirstChild(value); }
}
该脚本目前通过将其包装在一个函数中来调用,我可以将window
和document
Java对象传递到函数工作区。
document
是SpoofedDomElement
的特殊顶级版本(扩展了它),但在功能上与下面显示的示例相同。 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代码段,以便我可以传入对象以用作window
和document
。
欺骗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"
)。但是当任何一个值发生变化时,处理firstChild
或innerHtml
的值时,它会开始崩溃。
N.B。我在所有问题中都包含此部分,以记录我为未来的Google用户所尝试的内容。这可能有助于某人通过帮助头脑风暴来达成解决方案。
我试图使用框架(HtmlUnit)来评估Javascript。但我无法控制执行哪些Javascript片段。
以下是我目前正在研究寻找解决方案的问题。如果我发现了什么,我会报告回来。
firstChild
评估为函数吗?答案 0 :(得分:1)
您似乎正在尝试从Java代码实现脚本对象的友好访问,以及尝试在Java库/库之上提供脚本友好的API。
第一部分[从Java访问脚本对象]
除了javax.script.Invocable接口之外,您还可以使用JSObject。 Nashorn将脚本对象公开为jdk.nashorn.api.scripting.JSObject / .ScriptObjectMirror
的实例第二部分[从脚本中更友好地访问Java对象]
您可以使用“JSAdapter”在脚本本身编写脚本友好包装器。
文档和示例:
如果你更喜欢用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对象。
使用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