2015-07-08 28 views
7

Sono abbastanza nuovo per Nashorn e gli script sulla JVM e volevo sapere se posso ottenere il mio codice Java e javascript per comunicare in modo più efficace.Modo efficace per passare JSON tra java e javascript

Sto usando una lib di JS di terze parti che funziona con oggetti JS e nel mio codice java ho i dati che voglio passare come Map<String, Object> data.

Poiché JS di terze parti si aspetta di lavorare con oggetti JS semplici, non posso passare il mio data così com'è, sebbene il motore di script consenta di accedere a una mappa come se fosse un oggetto JS semplice.

Lo script che sto usando utilizza 'hasOwnProperty' sull'argomento dati e fallisce quando viene richiamato su un oggetto Java.

Quando ho provato a utilizzare Object.prototype.hasOwnProperty.call (data, 'myProp'), non funzionava e restituiva sempre 'false'. Il problema di base è che un oggetto Java non è un prototipo di oggetti javascript.

quello che ho finito per fare qualcosa di simile:

Map<String, Object> data; 

ObjectMapper mapper = new ObjectMapper(); 
String rawJSON = mapper.writeValueAsString(data); 

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); 

engine.eval('third_party_lib.js'); 
engine.eval('function doSomething(jsonStr) { var jsObj = JSON.parse(jsonStr); return doSomethingElse(jsObj); }'); 
Object value = ((Invocable) engine).invokeFunction("doSomething", rawJSON); 

Questo funziona come previsto, ma tutto questo JSON parsing avanti e indietro è pesante e si sente come ci potrebbe essere più semplice, più veloce e più semplice da fallo.

Quindi, c'è un modo migliore per passare JSON tra Java e Javascript o un modo per creare un oggetto JS compatibile nel mio codice Java?

Ho visto la guida this per il rendering del modello utilizzando mustache.js ma sta facendo praticamente la stessa cosa.

Grazie!

+0

cosa esattamente vuoi ottenere con questo? Per aggiungere un modo scriptable di richiamare le funzionalità della tua applicazione Java e operare sul modello di dati espunto all'interno della tua applicazione Java (l'intento progettato di Nashorn), o di imitare Node.js e invocare codice JavaScript arbitrario? – Gimby

+0

Non sto invocando affatto le funzioni Java da Javascript, esattamente l'opposto, voglio che la mia applicazione Java invochi una funzione javascript. Il mio caso specifico è il rendering con React.js, ma presumo che si tratti di un caso di uso comune per handlebars.js \ mustache.js o qualsiasi altra libreria javascript che utilizza oggetti JSON. –

risposta

5

Nashorn tratta gli oggetti java.util.Map appositamente. Nashorn consente di trattare le chiavi della mappa come "proprietà". Vedi anche https://wiki.openjdk.java.net/display/Nashorn/Nashorn+extensions#Nashornextensions-SpecialtreatmentofobjectsofspecificJavaclasses

Quindi se la tua mappa contiene "foo" come chiave, lo script può accedere a mapObj.foo per ottenere il suo valore. Non importa che lo script che hai valutato sia di terze parti. Finché lo script viene valutato da Nashorn, nashorn collegherà specificamente l'accesso alla proprietà Mappa e otterrà il risultato desiderato. Questo approccio evita la conversione della stringa JSON non necessaria e l'analisi del round trip (come lei stesso ha citato).

+0

Grazie per la risposta. Hai ragione, posso accedere a chiavi come qualsiasi altra proprietà, ma il mio problema è che l'oggetto Map non supporta la funzionalità nativa di javascript come "hasOwnProperty" che la lib di terze parti sta utilizzando. Ho aggiornato la domanda per rendere più chiaro il mio problema. –

+1

Ok, ho capito. In tal caso, sembra che il viaggio di andata e ritorno via JSON sia inevitabile. –

+0

Grazie per il suggerimento. Ecco un esempio di codice funzionante: http://stackoverflow.com/a/43667674/603516 – Vadzim