【问题标题】:executing code dynamically in groovy在 groovy 中动态执行代码
【发布时间】:2014-11-21 13:07:58
【问题描述】:

我正在尝试在 groovy 中动态运行代码。我有someNode[0],这是变量var1中的值

然后我像这样添加双引号

var2 = "\""+var1+"\""

然后我尝试运行它

request.abc."$var2"=Value

我看到here 可以在属性和方法上执行此类操作。但是上面的代码不起作用。给我错误

An error occurred [Cannot set property '"someNode[0]"' on null object], see error log for details

感谢任何帮助。谢谢。

编辑 这是我的请求的sn-p

{
   "app":{
      "bundle":"531323947",
      "cat":[
         "IAB1",
         "IAB9",
         "IAB9-30",
         "entertainment",
         "games"
      ],
      "id":"agltb3B1Yi1pbmNyDAsSA0FwcBitsL4UDA",
      .
      .

我要操作的字段是cat[0],即IAB1(我只是在上面写的代码中使用了abcsomeNode[0],但实际上它们是appcat[0]

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

感谢您的帮助

【问题讨论】:

  • 怎么样 var2 = var1 request.abc."$var2"=Value
  • @vahid 感谢您的回复。我试图跑var2 = var1request.abc."$var2"=Value,但它给了我同样的错误An error occurred [Cannot set property 'someNode[0]' on null object], see error log for details
  • 通常 [0] 告诉 groovy 返回任何数组的第一个元素 - 它可能与此有关 - 有没有办法在你设置好值后删除它并添加它?
  • 你能告诉我们你的要求吗? @vahid 是对的,虽然您可以通过字符串访问,但对于数组来说可能并不容易。您上面的代码可能已经失败,因为“请求”中没有“abc”。
  • @cfrick 我编辑了问题以显示请求。谢谢

标签: grails groovy


【解决方案1】:

一种方法是通过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'

【讨论】:

  • 您应该非常小心地为Eval 提供用户内容!如果这是通过一些带有用户内容的网络界面提供的,我宁愿使用解析器。
  • 我尝试了上述解决方案,但收到此错误 An error occurred [startup failed:Script1.groovy: 1:[parsed_MessageBody.app.cat[0]] is a constant expression, but it should be a variable expression at line: 1 column: 33. File: Script1.groovy @ line 1, column 33. 'parsed_MessageBody.app.cat[0]' = 'Value'^1 error], see error log for details 。不知道发生了什么。有什么想法吗?
  • @user1207289 'parsed_MessageBody.app.cat[0]' = 'Value' 看起来不对。它应该是parsed_MessageBody.app.cat[0] = 'Value'(第一个字符串上没有引号)
  • 感谢您的指出,我会尝试更改并发布结果。
  • 现在工作正常。非常感谢,尽管我仍然需要找出 Eval.me('request', request, "$var = 'new value'") 在做什么。我知道eval,但要了解您在 eval 中传递的第一个参数。第二和第三我有点理解。
【解决方案2】:

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

  1. 直接使用put & get 方法。
  2. 使用括号[]
  3. 使用缺少的属性作为映射键(即您使用它的方式)。

对于您想要实现的目标,即从变量键访问值,使用方法 1 或 2 比方法 3 更容易,而方法 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"
    }
}

【讨论】:

  • 在我的情况下,我实现这一点的唯一问题是cat[0] 在一个变量中。在我看来,再次解析 cat[0] 的开销很大。我不能像 def level1 = 'cat'node[0] = 'new value' 这样的硬编码。但在我看来,对于任何其他情况来说,这都是一个好方法。我会接受以下答案,因为它非常适合我的代码。我会提高你的答案,因为我从中吸取了教训。再次感谢您的意见。
猜你喜欢
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-30
  • 2020-03-18
  • 2012-12-15
  • 2013-08-16
相关资源
最近更新 更多