开发者

How to execute Javascript code from groovy and get the results as a map?

开发者 https://www.devze.com 2023-03-13 04:14 出处:网络
How can I get the results of executed javascript code from groovy? I tried the following, but I always get back the string \"world\". I would have expected an object or map.

How can I get the results of executed javascript code from groovy? I tried the following, but I always get back the string "world". I would have expected an object or map.

import javax.script.ScriptEngineManager
import javax.script.SimpleBindings

def manager = new ScriptEn开发者_开发问答gineManager()
manager.getEngineByName("JavaScript").eval("""
    {hello: name}
""", [name:'world'] as SimpleBindings)


Easy!

You could map the object to a variable, and return that...

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

Or you could keep track of a response Map object, and update that...

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

Groovy version: 2.4.5

Java version: 1.8.0_60


It's a bit tricky (and the only solution I can find is to use an internal sun.com class) :-/

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

That prints out:

[hello:world]

Doesn't feel a very clean way of doing things (and would probably require some work if you have a map of arrays for example)

But the best I can find :-/

0

精彩评论

暂无评论...
验证码 换一张
取 消