更新:我错误地将普通JavaScript对象命名为“JSON对象”。感谢那些在下面的评论中指出的人。所以我编辑了这个问题以避免进一步的误解。
我想知道是否可以使用JavaScript将JavaScript函数与JavaScript对象(可以描述为JSON字符串)作为参数调用netscape.javascript.JSObject。我尝试了以下代码段:
JSObject.getWindow(MyApplet.this).call(jsFunctionName, jsArgs);
根据to this article Java对象按原样传递给命名的JavaScript函数,并将根据它们所使用的上下文自动转换为某些JavaScript原语。这是否意味着无法传递描述的真实JavaScript对象作为JavaScript函数的一些JSON字符串,我必须寻找一种解决方法,比如在Java中将JSON字符串作为java.lang.String
参数进行准备,然后在JavaScript函数中对其进行解析以获得纯JavaScript对象?
答案 0 :(得分:2)
最好参考章节:«19.3 LiveConnect Data Conversion»。
jsArgs
内传递的每个对象都包含JavaObject wrapper。事实上,它是相同的JavaScript对象,具有所有公共属性和底层对象的方法。
E.g。如果我有以下Java类:
public class MyJavaClass {
public String name;
public int number;
public MyJavaClass(String n, int i) {
name = n;
number = num;
}
}
并调用JavaScript函数:
JSObject.getWindow(MyApplet.this).call("abFunc", new MyJavaClass("Kolya", 500));
JavaScript函数可能如下所示:
var abFunc = function(obj){
numberPlusThousand = (1000 + obj.number);
name = String(obj.name);
...
};
如果需要,您可以像任何其他JavaScript对象一样将其转换为JSON字符串。
作为call
函数的参数传递的JSObject类的实例将转换为相应的JavaScript对象。因此,如果您想避免Java代码在JavaScript代码中出现,您可以尝试创建新的JSObject实例,如下所示:
JSObject myJsObj = (JSObject) JSObject.eval("{}");
并添加新属性:
myJsObj.setMember("name", JSObject.eval("'Kolya'"));
myJsObj.setMember("number", 500);
或者像这样:
myJsObj.eval("self.name = 'Kolya'");
myJsObj.eval("self.number = 500");
在我看来,将Java中的JavaScript对象表示为map更方便,使用Gson之类的库将它们作为JSON字符串传递给JavaScript,并使用JSON.parse()将它们转换为JavaScript对象。
看看这个Gson用法:
Map m1 = ImmutableMap.of("id", "Kolya", "num", 500);
Map m2 = ImmutableMap.of("marks", new byte[] {5, 4, 5, 3});
Map m = ImmutableMap.of("m1", m1, "m2", m2, "l", ImmutableList.of("str", 234L, false));
System.out.println(new Gson().toJson(m));
// {"m1":{"id":"Kolya","num":500},"m2":{"marks":[5,4,5,3]},"l":["str",234,false]}
ImmutableMap
和ImmutableList
来自Guava libraries。