Domanda

Ho il seguente:

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

Come posso convertire l'oggetto risultato di tipo sun.org.mozilla.javascript.internal.NativeArray in un array java corrispondente? Qualcuno può mostrarmi un esempio di codice funzionante dove viene fatto? Dovrebbe funzionare per array String e Integer. Inoltre, sarebbe bello sapere dove cercare altre conversioni di tipi di dati tra il motore di Rhino e Java.

A proposito, Conosco questa pagina ma sto davvero cercando un esempio di codice funzionante.

È stato utile?

Soluzione

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);
}

Altri suggerimenti

Non sono sicuro che fosse il caso quando questa domanda è stata posta per la prima volta, ma NativeArray implementa l'interfaccia java.util.List . Un modo semplice per convertire in un vero array Java è quindi:

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

Se Javascript è sotto il tuo controllo, puoi eseguire la trasformazione lì, come da questo documento . Quindi, per adattare il tuo esempio, qualcosa del tipo:

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;

Anche se, se non riesci a modificare Javascript, questo approccio non funzionerà e tu [i] avrai [/ i] un'istanza di sun.org.mozilla.javascript.internal.NativeArray come risultato . A quel punto penso che devi solo lanciarlo e affrontarlo direttamente, usando qualunque metodo pubblico esponga; probabilmente non è carino ma non vedo altre opzioni. In particolare, penso che l'unica cosa che puoi garantire al buon livello di Rhino sia che sarà un'istanza di Scriptable (e probabilmente ScriptableObject ), che non ti aiuta usalo come un array.

La risposta di Kevin sembra come un buon modo per andare qui (ed è simile a quello in cui stavo per modificare! :-))

Soluzione generale che utilizza JSON come intermedio di dati:

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());
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top