Grails 在groovy中动态执行代码

Grails 在groovy中动态执行代码,grails,groovy,Grails,Groovy,我试图在groovy中动态运行代码。我有someNode[0],它是变量var1 然后我像这样添加了双引号 var2 = "\""+var1+"\"" 然后我试着运行这个 request.abc."$var2"=Value 我看到在属性和方法上可以做类似的事情。但是上面的代码不起作用。给我错误 An error occurred [Cannot set property '"someNode[0]"' on null object], see error log for details 感

我试图在groovy中动态运行代码。我有
someNode[0]
,它是变量
var1

然后我像这样添加了双引号

var2 = "\""+var1+"\""
然后我试着运行这个

request.abc."$var2"=Value
我看到在属性和方法上可以做类似的事情。但是上面的代码不起作用。给我错误

An error occurred [Cannot set property '"someNode[0]"' on null object], see error log for details
感谢您的帮助。谢谢

编辑 这是我请求的一个片段

{
   "app":{
      "bundle":"531323947",
      "cat":[
         "IAB1",
         "IAB9",
         "IAB9-30",
         "entertainment",
         "games"
      ],
      "id":"agltb3B1Yi1pbmNyDAsSA0FwcBitsL4UDA",
      .
      .
我试图操作的字段是
cat[0]
,它是
IAB1
(我刚才在上面写的代码中使用了
abc
someNode[0]
,但实际上它们是
app
cat[0]

此外,在运行上述代码之前,我使用
jsonslurper
解析了请求


感谢您的帮助

一种方法是通过
Eval

def request =[
"app":[
    "bundle":"531323947",
    "cat":[
            "IAB1",
            "IAB9",
            "IAB9-30",
            "entertainment",
            "games"
    ],
]
]

assert request.app.cat[0]=='IAB1'
def var = 'request.app.cat[0]'
Eval.me('request', request, "$var = 'new value'")
assert request.app.cat[0]=='new value'

您正在访问/更新地图和列表中的值。
request.app
节点将是一个映射,
request.app.cat
节点将是一个列表。可以通过多种不同的方式获取和设置地图中的值:

  • 直接使用
    put
    get
    方法
  • 使用括号
    []
  • 使用缺少的属性作为映射键(即使用它的方式)
  • 对于您想要实现的目标,即访问变量键中的值,使用方法1或2而不是方法3(在
    GString
    中包含变量)要容易得多

    使用括号的示例:

    import groovy.json.JsonBuilder
    import groovy.json.JsonSlurper
    
    def request = new JsonSlurper().parseText '''{
            "app":{
                "bundle":"531323947",
                "cat":[
                    "IAB1",
                    "IAB9",
                    "IAB9-30",
                    "entertainment",
                    "games"
                ],
                "id":"agltb3B1Yi1pbmNyDAsSA0FwcBitsL4UDA"
            }
        }'''
    
    def level0 = 'app'
    def level1 = 'cat'
    
    def node = request[level0][level1]
    
    assert request instanceof Map
    assert node instanceof List
    assert node[0] == 'IAB1'
    
    node[0] = 'new value'
    assert node[0] == 'new value'
    
    println new JsonBuilder(request).toPrettyString()
    
    输出:

    {
        "app": {
            "cat": [
                "new value",
                "IAB9",
                "IAB9-30",
                "entertainment",
                "games"
            ],
            "id": "agltb3B1Yi1pbmNyDAsSA0FwcBitsL4UDA",
            "bundle": "531323947"
        }
    }
    

    var2=var1 request.abc怎么样?“$var2”=Value@vahid谢谢你的回复。我试图运行
    var2=var1
    request.abc.“$var2”=Value
    但它给了我相同的错误
    出现错误[无法在null对象上设置属性“someNode[0]”,有关详细信息,请参阅错误日志
    通常是[0]告诉groovy返回任何数组的第一个元素-它可能与此相关-您是否无法删除此元素并在获得值集后添加它?您能否向我们展示您的请求。@vahid是对的,虽然可以通过字符串进行访问,但对于数组来说可能不是那么容易。您上面的代码可能会失败,因为“请求”中没有“abc”。@cfrick我编辑了问题以显示请求。谢谢你,你真的应该小心用用户内容输入
    Eval
    !如果这是通过某个带有用户内容的web界面提供的,我宁愿使用解析器。我尝试了上述解决方案,但出现了此错误
    错误[startup failed:Script1.groovy:1:[parsed_MessageBody.app.cat[0]]是一个常量表达式,但在第1行第33列应该是一个变量表达式。文件:Script1.groovy@第1行第33列。“parsed_MessageBody.app.cat[0]”=“Value”^1 error],有关详细信息,请参阅错误日志。不知道发生了什么事。有什么想法吗?@user1207289
    'parsed_MessageBody.app.cat[0]='Value'
    看起来不对。应该是
    parsed\u MessageBody.app.cat[0]=“Value”
    (第一个字符串上没有引号)感谢您指出,我将尝试更改并发布结果。现在一切正常。非常感谢,不过我仍然需要知道
    Eval.me('request',request,“$var='newvalue')在做什么。我知道
    eval
    ,但要了解您在eval中传递的第一个参数。第二个和第三个我有点理解。在我的例子中,我唯一的问题是
    cat[0]
    在一个变量中。在我看来,再次解析
    cat[0]
    的开销很大。我不能像这样硬编码
    def level1='cat'
    node[0]='new value'
    。但在我看来,这是处理其他任何情况的好方法。我会接受下面的答案,因为它完全适合我的代码。我会记住你的答案,因为我从中吸取了教训。再次感谢您的投入。