在 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
...
答案 0 :(得分:3)
不幸的是,只有当您知道可用于访问要获取属性名称的对象的全局变量名称时,Errandir的解决方案才有效。您需要知道此名称才能将keys
方法添加到对象,然后使用JSObject
的{{3}}方法调用它。当然,如果有的话,可以将对象的全局名称传递给Java。这个解决方案看起来不太好,特别是当你无法在全局环境中引用你的对象时。
作为替代方案,我建议在评论中使用this
JSObject
的{{3}}方法,假设它将完成所有工作。确实如此。但令人失望的是,它只能在Mozilla Firefox和Opera中运行。在Internet Explorer 9和Google Chrome中(在Windows 7和Ubuntu 12.04 LTS下测试)this
方法的eval
始终引用applet的文档窗口,忽略哪个JavaScript对象JSObject
实例实际代表。我不知道这是一个错误还是只是call在这些浏览器中支持得非常差。
好消息是call
JSObject
方法在适当的上下文中执行指定的函数。牢记这一点,我终于找到了一个解决方案,可以检索JavaScript对象属性的名称列表。我们的想法是使用eval
方法在全局上下文中定义临时函数。此函数必须接收我们想要获取属性的JavaScript对象,并将这些属性的名称作为数组返回。之后,我们可以通过JSObject
的{{1}}方法调用临时函数,传递相关JavaScript对象的Java表示形式(call
在我的方法中或jsObject
听到问题)。最后,可以删除临时功能。
args
答案 1 :(得分:1)
作为解决方案,您可以将方法keys
定义为建议的here(您可以使用JSObject.eval(...)
在您的java代码中执行此操作)。然后你可以得到像这样的键:
JSObject keys = (JSObject)args.call("keys", Collections.EMPTY_LIST);
keys.getSlot(0);
答案 2 :(得分:-1)
Here below I print a String, please modify it to get whatever you need.
public final static String getKeys = "{var keys = [];for (var key in this) {keys.push(key);} keys;}";
private static String printProperties(final Object o,
final boolean printType,
final int level,
final String tab) {
final StringBuilder sb = new StringBuilder(100);
if (printType) {
sb.append("(");
sb.append(o.getClass().getSimpleName());
sb.append(") ");
}
if (o instanceof JSObject) {
sb.append("{\n");
final JSObject js = (JSObject) o;
final JSObject keys = (JSObject) js.eval(getKeys);
boolean needComma = false;
for (int i = 0;; i++) {
final String key = (String) keys.getSlot(i);
if ((key != null) && !(key.equals("undefined"))) {
final Object val = js.getMember(key);
if (!needComma) {
needComma = true;
} else {
sb.append(",\n");
}
sb.append(multitab(tab, level));
sb.append(key);
sb.append(":");
sb.append(printProperties(val, printType, level + 1, tab));
} else {
break;
}
}
sb.append("\n");
sb.append(multitab(tab, level - 1));
sb.append("}");
} else {
sb.append(o);
}
return sb.toString();
}
private final static String tab = " ";
private static String multitab(final String tab,
int i) {
final StringBuilder sb = new StringBuilder();
while (i-- > 0) {
sb.append(tab);
}
return sb.toString();
}