java-如何从JSObject转换为Map(viceversa)或列出JSObject成员
作者:互联网
在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)
我所拥有的只是一个例外:
netscape.javascript.JSException: No such slot 0 on JavaScript object
...
解决方法:
不幸的是,仅当您知道可用于访问要获取其属性名称的对象的全局变量名称时,Errandir的解决方案才有效.您需要知道此名称,以便能够将keys方法添加到对象,并在以后使用JSObject的call方法调用它.当然,您可以将对象的全局名称传递给Java.这种解决方案看起来不太好,尤其是当您无法在全局上下文中引用对象时.
作为替代方案,我建议在注释中使用JSObject的eval方法中的该方法,假设它可以完成所有工作.确实如此.但令人失望的是,它只能在Mozilla Firefox和Opera中按预期方式工作.在Internet Explorer 9和Google Chrome(在Windows 7和Ubuntu 12.04 LTS下测试)中,此eval方法始终引用applet的文档窗口,而忽略了实际表示哪个JavaScript对象JSObject实例.我不知道这些浏览器是否支持bug还是仅仅是LiveConnect.
好消息是JSObject的调用方法在适当的上下文中执行指定的函数.牢记这一点,我终于找到了一种解决方案,该解决方案可如何检索JavaScript对象属性的名称列表.这个想法是使用eval方法在全局上下文中定义一个临时函数.该函数必须接收一个我们想要获取其属性的JavaScript对象,并以数组形式返回这些属性的名称.之后,我们可以通过JSObject的调用方法来调用临时函数,该方法传递有关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;
}
标签:applet,jsobject,json,javascript,java 来源: https://codeday.me/bug/20191201/2078287.html