将 Java 脚本属性连接到 Java 对象
Connecting Javascript properties to Java object
问题
我正在尝试将 Java 对象提供给通常在网页的文档对象模型 (DOM) 上运行的脚本。在大多数情况下,这会按预期运行。但是我在处理 DOM 元素的 attributes/properties 时遇到了问题。
一个特定的 属性 利益链是 somediv.firstChild.href
。我想不通的是如何动态获取 firstChild
属性 值。目前我能想到的最简单的方法是使用source.replaceAll("firstChild", "firstChild()");
强制firstChild
属性调用函数firstChild()
。然而,这最终会打开一个新的蠕虫罐头。
问题
如何定义可以传递给 javascript 函数的对象,该函数可以通过 DOM 进行操作?
背景
从 C# 中学习
在进入 Java 之前,我学过 C#。在 C# 中,setter 和 getter 的概念非常普遍。如果这个接口方法在 Java 中可用,我的问题就会得到解决。
public string firstChild {
get { return this.getFirstChild(); }
set { this.setFirstChild(value); }
}
当前实施
当前通过将脚本包装在函数中调用脚本,我可以将 window
和 document
Java 对象传入函数的工作区。
document
是 SpoofedDomElement
的特殊顶级版本(扩展它),但在功能上与下面显示的示例相同。 window
是另一个具有处理事件侦听器的最少功能的对象。
Java用于在 DOM
上运行的脚本(片段)
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
并在下一节中使用。
Java 评估代码 Javascript
String wrappedSource = "var scriptToInvoke = function(window, document){"
+ "\n" + theOriginalSource // from above
+ "\n};"
Object result = invocable.invokeFunction("scriptToInvoke", window, document);
此代码段包装了 javascript 代码段,以便我可以传入对象以用作 window
和 document
.
Java class是恶搞 DOM 元素
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";
}
上面的 classes 处理了代码中不相关的部分(例如赋值 somediv.style.display = "block"
)。但是当处理 firstChild
或 innerHtml
的值时,当其中一个值发生变化时,它开始崩溃。
过去的工作
N.B. 我在所有问题中都包含了这一部分,以记录我为 Google 到达这里的未来 SO 用户所做的尝试。这可能会帮助某人通过头脑风暴找到解决方案。
尝试过的解决方案
我试图使用框架 (HtmlUnit) 来评估 Java 脚本。但我无法控制执行了哪些 Java 脚本片段。
可能的解决方案
以下是我目前正在研究寻找解决方案的问题。如果我发现任何东西,我会报告回来。
- 有没有办法在 Java 中模拟 C# getter/setter 行为?
- Java脚本可以将
firstChild
作为函数求值吗?
- 有没有一种方法可以在 Java 脚本中使用 getter/setter 创建包装器来调用我的 Java class 的函数?
- 是否有用于 Nashorn(或类似)的 Apache Commons 库没有完整的模拟框架(例如 Selenium)那么重?
看来您正在尝试从 Java 代码实现对脚本对象的友好访问,并试图在 java 之上提供脚本友好的 API library/libraries.
第一部分[从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 的脚本扩展也可用于捕获每个对象基础上的未知 property/method 访问:
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
问题
我正在尝试将 Java 对象提供给通常在网页的文档对象模型 (DOM) 上运行的脚本。在大多数情况下,这会按预期运行。但是我在处理 DOM 元素的 attributes/properties 时遇到了问题。
一个特定的 属性 利益链是 somediv.firstChild.href
。我想不通的是如何动态获取 firstChild
属性 值。目前我能想到的最简单的方法是使用source.replaceAll("firstChild", "firstChild()");
强制firstChild
属性调用函数firstChild()
。然而,这最终会打开一个新的蠕虫罐头。
问题
如何定义可以传递给 javascript 函数的对象,该函数可以通过 DOM 进行操作?
背景
从 C# 中学习
在进入 Java 之前,我学过 C#。在 C# 中,setter 和 getter 的概念非常普遍。如果这个接口方法在 Java 中可用,我的问题就会得到解决。
public string firstChild {
get { return this.getFirstChild(); }
set { this.setFirstChild(value); }
}
当前实施
当前通过将脚本包装在函数中调用脚本,我可以将 window
和 document
Java 对象传入函数的工作区。
document
是 SpoofedDomElement
的特殊顶级版本(扩展它),但在功能上与下面显示的示例相同。 window
是另一个具有处理事件侦听器的最少功能的对象。
Java用于在 DOM
上运行的脚本(片段)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
并在下一节中使用。
Java 评估代码 Javascript
String wrappedSource = "var scriptToInvoke = function(window, document){"
+ "\n" + theOriginalSource // from above
+ "\n};"
Object result = invocable.invokeFunction("scriptToInvoke", window, document);
此代码段包装了 javascript 代码段,以便我可以传入对象以用作 window
和 document
.
Java class是恶搞 DOM 元素
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";
}
上面的 classes 处理了代码中不相关的部分(例如赋值 somediv.style.display = "block"
)。但是当处理 firstChild
或 innerHtml
的值时,当其中一个值发生变化时,它开始崩溃。
过去的工作
N.B. 我在所有问题中都包含了这一部分,以记录我为 Google 到达这里的未来 SO 用户所做的尝试。这可能会帮助某人通过头脑风暴找到解决方案。
尝试过的解决方案
我试图使用框架 (HtmlUnit) 来评估 Java 脚本。但我无法控制执行了哪些 Java 脚本片段。
可能的解决方案
以下是我目前正在研究寻找解决方案的问题。如果我发现任何东西,我会报告回来。
- 有没有办法在 Java 中模拟 C# getter/setter 行为?
- Java脚本可以将
firstChild
作为函数求值吗? - 有没有一种方法可以在 Java 脚本中使用 getter/setter 创建包装器来调用我的 Java class 的函数?
- 是否有用于 Nashorn(或类似)的 Apache Commons 库没有完整的模拟框架(例如 Selenium)那么重?
看来您正在尝试从 Java 代码实现对脚本对象的友好访问,并试图在 java 之上提供脚本友好的 API library/libraries.
第一部分[从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 的脚本扩展也可用于捕获每个对象基础上的未知 property/method 访问:
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