2009-09-16 12 views
17

Mam następujący:Jak przekonwertować tablice Rhino-JavaScript do Java-Arrays

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

jaki sposób można przekonwertować obiekt wynik, który typu sun.org.mozilla.javascript.internal.NativeArray Do odpowiadająca tablica java? Czy ktoś może mi pokazać kod roboczy, gdzie to jest zrobione? Powinien działać w przypadku macierzy String i Integer. Poza tym dobrze byłoby wiedzieć, gdzie szukać innych konwersji danych między silnikiem rhino a Javą.

Btw, i know this page ale naprawdę szukam działającej próbki kodu.

Odpowiedz

22
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); 
} 
+0

Dzięki za pomoc głupiego faceta ;-) Życzę wszystkim odpowiedzi byłoby to, że precyzyjne, krótkie i działające! – Chris

+0

Zastanawiam się, dlaczego nie można rzucić całej tablicy getIds na liczbę całkowitą []. Otrzymuję wyjątek ClassCastException. No dobrze – TheLQ

7

Jeśli JavaScript jest pod twoją kontrolą, możesz dokonać transformacji tam, zgodnie z this document. Tak, aby dostosować swój przykład, coś jak:

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; 

Chociaż, jeśli nie można zmienić Javascript podejście to nie będzie działać, a ty [i] będzie [/ i] mają wystąpienie sun.org .mozilla.javascript.internal.NativeArray jako zmienną result. W tym momencie myślę, że wystarczy rzucić i zająć się nim bezpośrednio, używając wszelkich publicznych metod, które on eksponuje; prawdopodobnie nie jest ładna, ale nie widzę żadnych innych opcji. W szczególności myślę, że jedyną rzeczą, którą możesz zagwarantować na miłym poziomie Rhino jest to, że będzie to instancja Scriptable (i prawdopodobnie ScriptableObject), która nie pomoże ci jej użyć jako tablicy.

Kevin's answer wygląda jak dobra droga tutaj (i jest podobny do tego, co było po prostu o edycję w! :-))

8

Nie jestem pewien, czy to był przypadek, kiedy to pierwsze pytanie zadano, ale NativeArray implementuje interfejs java.util.List. Prosty sposób na konwersję do prawdziwej tablicy Java jest zatem:

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

jdk1.6.0_45 mówi, że sun.org.mozilla.javascript.internal.NativeArray nie można przesłać na java.util.List – pal

+0

@pal NativeArray zdecydowanie implementuje List w nowszych wersjach Rhino, ale nie jestem pewien kiedy był pierwszy przypadek. Zobacz [tutaj] (http://javadox.com/org.mozilla/rhino/1.7R3/org/mozilla/javascript/NativeArray.html). –

+1

Nawiasem mówiąc, Nashorn (silnik JavaScript zawarty w Java 8) niestety zwraca obiekty klasy (ScriptObjectMirror), która implementuje Map zamiast List. Jeśli chcesz, aby twój kod działał zarówno w Javie 7, jak i 8+, musisz wykonać sprawdzenie instancji. –

0

rozwiązanie ogólne korzystania Jason danych pośrednich:

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()); 
} 
Powiązane problemy