java - español - rhino jar
Cómo convertir matrices Rhino-JavaScript a Java-Arrays (4)
No estoy seguro si fue el caso cuando se hizo esta pregunta por primera vez, pero NativeArray
implementa la interfaz java.util.List
. Por lo tanto, una forma sencilla de convertir a una matriz Java real es:
Object[] array = ((List<?>) result).toArray();
Tengo los siguientes
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
jsEngine.eval("function getArray() {return [1,2,3,4,5];};");
Object result = jsEngine.eval("getArray();");
¿Cómo puedo convertir el objeto de resultado que es de tipo sun.org.mozilla.javascript.internal.NativeArray a una matriz java correspondiente? ¿Puede alguien mostrarme un ejemplo de código de trabajo donde se hace esto? Debería funcionar para arreglos de cadenas y enteros. Además, sería bueno saber dónde buscar otras conversiones de tipo de datos entre el motor de rinoceronte y Java.
Por cierto, conozco esta página pero realmente estoy buscando un ejemplo de código que funcione.
Si el Javascript está bajo su control, puede hacer la transformación allí, según este documento . Así que para adaptar tu ejemplo, algo como:
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;
Aunque, si no puede cambiar el Javascript, este enfoque no funcionará, y [i] tendrá [/ i] una instancia de sun.org.mozilla.javascript.internal.NativeArray como su variable de result
. En ese momento creo que solo necesitas lanzarlo y lidiar con él directamente, usando cualquier método público que exponga; Probablemente no sea bonito pero no veo ninguna otra opción. En particular, creo que lo único que puede garantizar a un nivel agradable de Rhino es que será una instancia de Scriptable
(y probablemente ScriptableObject
), que no le ayuda a usarlo como una matriz.
La respuesta de Kevin parece ser una buena manera de ir aquí (y es similar a lo que estaba a punto de editar en :-))
Solución general utilizando JASON como intermediario de datos:
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());
}
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);
}