如何将 Rhino-JavaScript 数组转换为 Java 数组

发布于 2024-08-04 11:28:34 字数 566 浏览 6 评论 0原文

我有以下内容:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
jsEngine.eval("function getArray() {return [1,2,3,4,5];};");
Object result = jsEngine.eval("getArray();");

如何将 sun.org.mozilla.javascript.internal.NativeArray 类型的结果对象转换为相应的 java 数组?有人可以向我展示一个工作代码示例吗?它应该适用于字符串和整数数组。另外,如果知道在哪里可以找到 rhino 引擎和 java 之间的其他数据类型转换,那就太好了。

顺便说一句,我知道这个页面,但我真的在寻找一个有效的代码示例。

I have the following:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
jsEngine.eval("function getArray() {return [1,2,3,4,5];};");
Object result = jsEngine.eval("getArray();");

How can i convert the result object which is of type sun.org.mozilla.javascript.internal.NativeArray to a corresponding java array? Can somone show me a working code sample where this is done? It should work for String and Integer arrays. Plus, it would be great to know where to look for other data type conversions between the rhino engine and java.

Btw, i know this page but i'm really looking for a working code sample.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

孤千羽 2024-08-11 11:28:35
NativeArray arr = (NativeArray) result;
Object [] array = new Object[(int) arr.getLength()];
for (Object o : arr.getIds()) {
    int index = (Integer) o;
    array[index] = arr.get(index, null);
}
NativeArray arr = (NativeArray) result;
Object [] array = new Object[(int) arr.getLength()];
for (Object o : arr.getIds()) {
    int index = (Integer) o;
    array[index] = arr.get(index, null);
}
枉心 2024-08-11 11:28:35

我不确定第一次提出这个问题时是否是这种情况,但 NativeArray 实现了 java.util.List 接口。因此,转换为真正的 Java 数组的简单方法是:

Object[] array = ((List<?>) result).toArray();

I'm not sure if it was the case when this question was first asked, but NativeArray implements the java.util.List interface. A simple way to convert to a real Java array is therefore:

Object[] array = ((List<?>) result).toArray();
嘿看小鸭子会跑 2024-08-11 11:28:35

如果 Javascript 在您的控制之下,您可以按照 此文档。因此,要调整您的示例,例如:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
jsEngine.eval("function getArray() {return [1,2,3,4,5];};");
String convertFuncSrc =
     "function convertArray(type, arr) {"
   + "  var jArr = java.lang.reflect.Array.newInstance(type, arr.length);"
   + "  for (var i = 0; i < arr.length; i++) { "
   + "    jArr[i] = arr[i];"
   + "  }"
   + "  return jArr;"
   + "};";
jsEngine.eval(convertFuncSrc);
Object result = jsEngine.eval("convertArray(java.lang.Integer.TYPE, getArray());");
int[] javaArray = (int[])result;

尽管如此,如果您无法更改 Javascript,则此方法将不起作用,并且您[i]将[/i]拥有一个 sun.org.mozilla.javascript.internal 的实例。 NativeArray 作为您的 result 变量。在这一点上,我认为您只需要使用它公开的任何公共方法直接转换和处理它;它可能不漂亮,但我没有看到任何其他选择。特别是,我认为在很好的 Rhino 级别上您唯一可以保证的是它将是 Scriptable 的实例(可能是 ScriptableObject ),这对您没有帮助将其用作数组。

凯文的答案看起来不错到这里的方式(与我刚刚要编辑的内容类似!:-))

If the Javascript is under your control, you could do the transformation there, as per this document. So to adapt your example, something like:

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
jsEngine.eval("function getArray() {return [1,2,3,4,5];};");
String convertFuncSrc =
     "function convertArray(type, arr) {"
   + "  var jArr = java.lang.reflect.Array.newInstance(type, arr.length);"
   + "  for (var i = 0; i < arr.length; i++) { "
   + "    jArr[i] = arr[i];"
   + "  }"
   + "  return jArr;"
   + "};";
jsEngine.eval(convertFuncSrc);
Object result = jsEngine.eval("convertArray(java.lang.Integer.TYPE, getArray());");
int[] javaArray = (int[])result;

Although, if you can't change the Javascript this approach won't work, and you [i]will[/i] have an instance of sun.org.mozilla.javascript.internal.NativeArray as your result variable. At which point I think you just need to cast and deal with it directly, using whatever public methods it exposes; it's probably not pretty but I don't see any other options. In particular I think the only thing you can guarantee at the nice Rhino level is that it will be an instance of Scriptable (and probably ScriptableObject), which doesn't help you use it as an Array.

Kevin's answer looks like a good way to go here (and is similar to what I was just about to edit in! :-))

乖乖兔^ω^ 2024-08-11 11:28:35

就我而言,我想在脚本中生成一个 Java 数组。 (此用例也符合问题。)

遵循 创建Java 数组,我想出了

var javaArray = java.lang.reflect.Array.newInstance(java.lang.Integer, jsArray.length);
for (var i = 0; i < javaArray.length; i++) {
  javaArray[i] = new java.lang.Integer(jsArray[i]);
}

In my case I wanted to produce a Java array within the script. (This use case also matches the question.)

Following Creating Java Arrays, I came up with

var javaArray = java.lang.reflect.Array.newInstance(java.lang.Integer, jsArray.length);
for (var i = 0; i < javaArray.length; i++) {
  javaArray[i] = new java.lang.Integer(jsArray[i]);
}
已下线请稍等 2024-08-11 11:28:35

使用 JASON 作为数据中间体的通用解决方案:

Object result = jsEngine.eval("JSON.stringify(getArray())");    
JsonReader jsonReader = Json.createReader(new StringReader(result.toString()));
JsonArray jsonArray = jsonReader.readArray();
jsonReader.close();
int[] numbers = new int[jsonArray.size()];
int index = 0;
for(JsonValue value : jsonArray){
    numbers[index++] = Integer.parseInt(value.toString());
}

General solution using JASON as data intermediate:

Object result = jsEngine.eval("JSON.stringify(getArray())");    
JsonReader jsonReader = Json.createReader(new StringReader(result.toString()));
JsonArray jsonArray = jsonReader.readArray();
jsonReader.close();
int[] numbers = new int[jsonArray.size()];
int index = 0;
for(JsonValue value : jsonArray){
    numbers[index++] = Integer.parseInt(value.toString());
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文