我正在尝试在JavaScript代码中生成数据结构,并处理来自Java(Java 6或7中的Rhino)的结果。
我成功地使用以下方法从Java调用JS函数:
Object result = invocableEngine.invokeFunction(functionName, parameters);
现在,在JS方面,该结果是一个JSON数据结构如下:
{
"key1" : { "key1_1" : "value1_1", "key1_2" : 11 },
"key2" : [ { "key2_1": "foo2"
, "key2_1" : "bar2" },
{ "key2_1": "foo2"
, "key2_1" : "bar2"
, "key2_3" : [1,2,3] } ]
}
然而,在Java方面,"结果"是sun.org.mozilla.javascript.internal.NativeObject
我有没有办法将它转换为合理的Java数据结构,而没有将JSON序列化为字符串然后使用Gson解析它的开销?
假设目前数据结构的定义合理,例如: 我知道该对象是一个带键和#34; key1"和" key2",第一个映射到带有键" key1_1"的散列。和" key1_2&#34 ;;第二个映射到一个哈希数组,每个哈希都有键" key2_1"和" key2_2"这是标量和" key2_3"这是一个数组。
我的两个优先事项是:
答案 0 :(得分:1)
这是从NativeObject到JSONObject的代码。 我认为从NativeObject到Map都是相似的。
public static JSONObject toJsonObject(NativeObject nativeObject)
{
JSONObject object = new JSONObject();
Set<Entry<Object, Object>> entrySet = nativeObject.entrySet();
for (Entry<Object, Object> entry : entrySet)
{
try
{
if (entry.getValue() instanceof String)
{
object.put(entry.getKey().toString(), new JSONObject(entry.getValue().toString()));
}
else if (entry.getValue() instanceof NativeArray)
{
object.put(entry.getKey().toString(), toJsonArray((NativeArray) entry.getValue()));
}
else if (entry.getValue() instanceof NativeObject)
{
object.put(entry.getKey().toString(), toJsonObject((NativeObject) entry.getValue()));
}
}
catch (JSONException e)
{
try
{
object.put(entry.getKey().toString(), entry.getValue().toString());
}
catch (JSONException ignored)
{
}
}
}
return object;
}
public static JSONArray toJsonArray(NativeArray nativeArray)
{
JSONArray array = new JSONArray();
for (Object o : nativeArray)
{
if (o instanceof NativeObject)
{
array.put(toJsonObject((NativeObject) o));
}
else if (o instanceof NativeArray)
{
array.put(toJsonArray((NativeArray) o));
}
else
{
try
{
array.put(new JSONObject(o.toString()));
}
catch (JSONException e)
{
array.put(o.toString());
}
}
}
return array;
}
答案 1 :(得分:0)
你可以解析任何json字符串&#34; object&#34;使用Gson
将其解析为LinkedTreeMap
,如下所示:
import com.google.gson.internal.LinkedTreeMap;
String json = <your raw json>
LinkedTreeMap map = new Gson().fromJson(json, LinkedTreeMap.class);
在解析您的示例输入后,以下是如何使用它的示例:
System.out.println(((List<LinkedTreeMap>)map.get("key2")).get(1).get("key2_3"));
输出:
[1.0, 2.0, 3.0]
事先知道结构是有帮助的,但并不重要,因为你可以在得到它时检查每个节点的类型。
至于性能,我创建了4个密钥的样本输入,每个密钥在列表中有400多个条目。在JVM警告之后,我的低规格旧笔记本电脑上的解析只用了2ms。
答案 2 :(得分:-1)
您可以从json内部构建java对象。
像这样的东西(我正在构建新的java.lang.String,但同样你可以构建自己的类):
java -jar js.jar
Rhino 1.7 release 5 2015 01 29
js> str=new java.lang.String("Hello world")
Hello world
js> java.lang.System.out.println(str)
Hello world