在 Javascript 中,我有以下代码:
var r=applet.foo({var0:99,var1:'foo',var2:applet});
在我的 Java 小程序中,我有以下内容:
public JSObject foo(JSObject args){
System.out.println("The function is correctly invoked");
//In fact, the following works perfectly:
System.out.println("var1 is:"+(String)args.getMember("var1"));
JSObject w=JSObject.getWindow(this);
JSObject j=(JSObject)w.eval("new Object();");
Map m=new Hashmap();
//TODO here all the keys and values of args should be added to m
m.put("hello","world");
//TODO here all the keys and values of m should be added to j
return j;
}
如何做到这一点? (待办事项)
阅读 http://docstore.mik.ua/orelly/web/jscript/ch19_06.html ,我注意到 JSObject 有一个 getSlot 方法,但如果我这样做了
args.getSlot(0)
我只有一个异常(exception):
netscape.javascript.JSException: No such slot 0 on JavaScript object
...
最佳答案
不幸的是,Errandir 的解决方案只有在您知道可用于访问您想要获取其属性名称的对象的全局变量名称时才有效。您需要知道此名称才能将 keys
方法添加到对象,并使用 JSObject
的 call 调用它。方法稍后。当然,如果有,您可以将对象的全局名称传递给 Java。这个解决方案看起来不太好,尤其是当您不能在全局上下文中引用您的对象时。
作为替代方案,我建议使用 JSObject
的 eval 的 this
注释中的方法假设它将完成所有工作。确实如此。但令人失望的是,它只能在 Mozilla Firefox 和 Opera 中按预期工作。在 Internet Explorer 9 和 Google Chrome 中(在 Windows 7 和 Ubuntu 12.04 LTS 下测试)this
的 eval
方法总是引用 applet 的文档窗口忽略哪个 JavaScript 对象 JSObject
实例实际表示。我不知道这是一个错误还是简单的 LiveConnect这些浏览器的支持很差。
好消息是 JSObject
的 call
方法在适当的上下文中执行指定的函数。牢记这一点,我终于找到了一个解决方案,即如何检索 JavaScript 对象属性的名称列表。这个想法是使用 eval
方法在全局上下文中定义一个临时函数。该函数必须接收一个我们想要获取其属性的 JavaScript 对象,并将这些属性的名称作为数组返回。之后,我们可以通过 JSObject
的 call
方法调用临时函数,传递有关 JavaScript 对象的 Java 表示(下面我的方法中的 jsObject
或args
在问题中听起来)。最后,可以删除临时功能。
public static ArrayList<String> getJsObjectPropertiesNames(Applet applet, JSObject jsObject) {
if (applet == null || jsObject == null)
return null;
// Retrieving global context - a JSObject representing a window applet belongs to
JSObject globalContext;
try {
globalContext = JSObject.getWindow(applet);
}
catch (JSException ex) {
return null;
}
// Checking whether passed object is not an array
try {
jsObject.getSlot(0);
return null;
}
catch (JSException e) {
}
String keysFunctionName = String.format("_getKeys%d", Calendar.getInstance().getTimeInMillis());
jsObject.eval("window['" + keysFunctionName + "'] = function(jsObject) { return Object.keys(jsObject) }");
JSObject propertiesNamesJsObject = (JSObject)globalContext.call(keysFunctionName, new Object[] { jsObject });
jsObject.eval("delete(window['" + keysFunctionName + "'])");
ArrayList<String> propertiesNames = new ArrayList<>();
try {
int slotIndex = 0;
while (true) {
Object propertyName = propertiesNamesJsObject.getSlot(slotIndex);
if (propertyName instanceof String)
propertiesNames.add((String)propertyName);
slotIndex++;
}
}
catch (JSException e) {
}
return propertiesNames;
}
关于java - 如何从 JSObject 转换为 Map(反之亦然)或列出 JSObject 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11350967/