简体   繁体   English

Groovy JsonBuilder:也使用变量名的字段名

[英]Groovy JsonBuilder: using field names that are variable names too

I'm using groovy.json.JsonBuilder and having trouble specifying a fieldname that is also the name of a variable in the current scope. 我正在使用groovy.json.JsonBuilder并且在指定字段名(在当前作用域中也是变量名)时遇到麻烦。

This works: 这有效:

System.out.println(new GroovyShell().evaluate(
          "def builder = new groovy.json.JsonBuilder();"
        + "def age = 23;"
        + "builder.example {"
        + "  name 'Fred';"
        + "  'age1' 27;"
        + "  blah {"
        + "    foo 'bar';"
        + "  };"
        + "};"
        + "return builder.toPrettyString()"));

And produces output: 并产生输出:

{
    "example": {
        "name": "Fred",
        "age1": 27,
        "blah": {
            "foo": "bar"
        }
    }
}

But this fails (the field 'age' for some reason conflicts with the variable): 但这失败了(字段“ age”由于某种原因与变量冲突):

System.out.println(new GroovyShell().evaluate(
          "def builder = new groovy.json.JsonBuilder();"
        + "def age = 23;"
        + "builder.example {"
        + "  name 'Fred';"
        + "  'age' 27;"
        + "  blah {"
        + "    foo 'bar';"
        + "  };"
        + "};"
        + "return builder.toPrettyString()"));

And produces an exception: 并产生一个异常:

groovy.lang.MissingMethodException: No signature of method: java.lang.Integer.call() is applicable for argument types: (Integer) values: [27]
Possible solutions: wait(), abs(), any(), wait(long), wait(long, int), max(int, int)
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:72)
    at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:48)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
    at Script1$_run_closure1.doCall(Script1.groovy:5)
    at Script1$_run_closure1.doCall(Script1.groovy)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:104)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:326)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:264)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
    at groovy.lang.Closure.call(Closure.java:421)
    at groovy.lang.Closure.call(Closure.java:415)
    at groovy.json.JsonDelegate.cloneDelegateAndGetContent(JsonDelegate.java:91)
    at groovy.json.JsonBuilder.invokeMethod(JsonBuilder.java:314)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:47)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:128)
    at Script1.run(Script1.groovy:3)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:444)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:482)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:453)

I do not want to change the name of my variable. 我不想更改变量的名称。 Is there some way to force JsonBuilder to accept the field name? 有什么方法可以强制JsonBuilder接受字段名称? As you can see, I tried to put it in quotes, but that didn't help. 如您所见,我试图将其用引号引起来,但这没有帮助。

Use delegate.age in order to refer to the surrounding closure instead of referring to the variable. 使用delegate.age来引用周围的闭包,而不是引用变量。

System.out.println(new GroovyShell().evaluate(
          "def builder = new groovy.json.JsonBuilder();"
        + "def age = 23;"
        + "builder.example {"
        + "  name 'Fred';"
        + "  delegate.age 27;"
        + "  blah {"
        + "    foo 'bar';"
        + "  };"
        + "};"
        + "return builder.toPrettyString()"));

should give you 应该给你

{
    "example": {
        "name": "Fred",
        "age": 27,
        "blah": {
            "foo": "bar"
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM