如何将Rhino产生的JSON数据结构(NativeObject)转换为Java数据结构?

问题描述 投票:6回答:3

我正在尝试在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进行解析的开销?

目前假设数据结构定义合理,例如我知道对象是键为“ key1”和“ key2”的哈希,第一个映射为键为“ key1_1”和“ key1_2”的哈希;第二个映射到哈希数组,每个哈希都有标量的键“ key2_1”和“ key2_2”,而数组是“ key2_3”。

我的两个优先顺序是:

  1. 性能(这是我对序列化+ Gson-parse保持警惕的原因之一)
  2. Java 6、7和8之间的可移植性(但是,我希望使用一种实质性更快的非便携式解决方案。
java json rhino
3个回答
0
投票

您可以通过将Gson解析为LinkedTreeMap来使用它解析任何json字符串“对象”,如下所示:

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。


0
投票

这是从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
投票

您可以从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
© www.soinside.com 2019 - 2024. All rights reserved.