【问题标题】:Groovy JsonBuilder: using field names that are variable names tooGroovy JsonBuilder:使用也是变量名的字段名
【发布时间】:2018-10-14 14:53:04
【问题描述】:

我正在使用groovy.json.JsonBuilder,但无法指定同时也是​​当前范围内变量名称的字段名。

这行得通:

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()"));

并产生输出:

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

但这失败了(字段“年龄”由于某种原因与变量冲突):

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()"));

并产生异常:

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)

我不想更改变量的名称。有没有办法强制 JsonBuilder 接受字段名?如您所见,我尝试将其放在引号中,但这没有帮助。

【问题讨论】:

    标签: java groovy


    【解决方案1】:

    使用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()"));
    

    应该给你

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

    【讨论】:

    • 啊哈!这正是我所追求的。我试过it.age,但不是delegate.age。我还没有完全理解闭包在构建器中是如何工作的。
    • This answer 可以为您提供有关委托、此和所有者的更多信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 1970-01-01
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    相关资源
    最近更新 更多