Comment exécuter du code Javascript de groovy et obtenir les résultats comme une carte?
-
27-10-2019 - |
Question
Comment puis-je obtenir les résultats du code javascript exécuté à partir groovy? J'ai essayé ce qui suit, mais je reçois toujours sur la corde « monde ». Je me serais attendu à un objet ou d'une carte.
import javax.script.ScriptEngineManager
import javax.script.SimpleBindings
def manager = new ScriptEngineManager()
manager.getEngineByName("JavaScript").eval("""
{hello: name}
""", [name:'world'] as SimpleBindings)
La solution
facile!
Vous pourriez mapper l'objet à une variable, et le retour que ...
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
Ou vous pouvez garder la trace d'un objet response
Carte et mise à jour ...
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
Version Groovy: 2.4.5
version Java: 1.8.0_60
Autres conseils
Il est un peu difficile (et la seule solution que je peux trouver est d'utiliser une classe sun.com
interne): - /
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
Que imprime:
[hello:world]
ne se sent pas une façon très propre de faire les choses (et aurait probablement besoin un peu de travail si vous avez une carte de tableaux par exemple)
Mais le meilleur que je peux trouver: - /