Come eseguire il codice JavaScript da Groovy e ottenere i risultati come mappa?
-
27-10-2019 - |
Domanda
Come posso ottenere i risultati del codice JavaScript eseguito da Groovy? Ho provato quanto segue, ma recupo sempre la stringa "mondo". Mi sarei aspettato un oggetto o una mappa.
import javax.script.ScriptEngineManager
import javax.script.SimpleBindings
def manager = new ScriptEngineManager()
manager.getEngineByName("JavaScript").eval("""
{hello: name}
""", [name:'world'] as SimpleBindings)
Soluzione
Facile!
Potresti mappare l'oggetto su una variabile e restituirlo ...
import javax.script.*
def bindings = [name:'world']
def response = new ScriptEngineManager()
.getEngineByName('javascript')
.eval("var r = {hello:name}; r;", bindings as SimpleBindings)
println response.hello // -> world
Oppure potresti tenere traccia di un response
Mappa l'oggetto e aggiorna quello ...
import javax.script.*
def bindings = [name:'world',response:[:]]
new ScriptEngineManager()
.getEngineByName('javascript')
.eval("var r = {hello:name}; response.data = r;", bindings as SimpleBindings)
println bindings.response.data.hello // -> world
Versione groovy: 2.4.5
Versione Java: 1.8.0_60
Altri suggerimenti
È un po 'complicato (e l'unica soluzione che riesco a trovare è usare un interno sun.com
classe) :-/
import javax.script.ScriptEngineManager
import javax.script.SimpleBindings
import sun.org.mozilla.javascript.internal.NativeObject
// A Category to parse NativeObject into a Map
class NativeObjectParser {
static Map asMap( NativeObject jsobj ) {
jsobj.allIds.inject( [:] ) { map, key ->
def value = jsobj.get( key, jsobj )
// Handle nested maps
map << [ (key):value instanceof NativeObject ? value.asMap() : value ]
}
}
}
// Your code as you had it before (apart from the JS defines a var, and returns that var object)
def manager = new ScriptEngineManager()
def ret = manager.getEngineByName("JavaScript").eval("""
var r = { 'hello': name }
r
""", [ name:'world' ] as SimpleBindings )
// Do the unwrapping
def map = use( NativeObjectParser ) {
ret.asMap()
}
println map
Che sta stampa:
[hello:world]
Non sente un modo molto pulito di fare le cose (e probabilmente richiederebbe un po 'di lavoro se si dispone di una mappa di array per esempio)
Ma il meglio che riesco a trovare:-/
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow