(这是对所提问题 here 的后续问题)
我使用 Groovy 的 JsonBuilder 动态生成以下 JSON:
{
"type": {
"__type": "urn",
"value": "myCustomValue1"
},
"urn": {
"__type": "urn",
"value": "myCustomValue2"
},
"date": {
"epoch": 1265662800000,
"str": "2010-02-08T21:00:00Z"
},
"metadata": [{
"ratings": [{
"rating": "NR",
"scheme": "eirin",
"_type": {
"__type": "urn",
"value": "myCustomValue3"
}
}],
"creators": [Jim, Bob, Joe]
}]
}
使用此代码:
def addUrn(parent, type, urnVal) {
parent."$type" {
__type "urn"
"value" urnVal
}
}
String getEpisode(String myCustomVal1, String myCustomVal2, String myCustomVal3) {
def builder = new groovy.json.JsonBuilder()
builder {
addUrn(delegate, "type", myCustomVal1)
addUrn(delegate, "urn", "some:urn:$myCustomVal2")
"date" {
epoch 1265662800000
str "2010-02-08T21:00:00Z"
}
"metadata" ({
ratings ({
rating "G"
scheme "eirin"
addUrn(delegate, "_type", "$myCustomVal3")
})
creators "Jim", "Bob", "Joe"
})
}
return root.toString();
}
由于第三次调用addUrn
(在嵌套的 ratings
元素下),代码抛出了StackOverflowError
。如果我注释掉该行,它就会完美地工作(除了我丢失了必要的信息 block 这一事实)。
- 为什么会发生这种情况?
- 如何将委托(delegate)设置为直接父级,例如
评分
?
我尝试过使用元类,但没有成功。
最佳答案
这很难看(笑),但会给你预期的结果:
def addUrn(parent, type, urnVal) {
parent."$type" {
__type "urn"
"value" urnVal
}
}
String getEpisode(String myCustomVal1, String myCustomVal2, String myCustomVal3) {
def builder = new groovy.json.JsonBuilder()
def root = builder {
addUrn(delegate, "type", myCustomVal1)
addUrn(delegate, "urn", "some:urn:$myCustomVal2")
"date" {
epoch 1265662800000
str "2010-02-08T21:00:00Z"
}
"metadata" ([{([
"ratings" ([{
rating "G"
scheme "eirin"
this.addUrn(delegate, "_type", "$myCustomVal3")
}]),
creators ("Jim", "Bob", "Joe")
])}])
}
println builder.toPrettyString()
}
注意:-
- 在上一个问题中,我错误地表示委托(delegate)已
指代直系父辈。实际上它确实指的是立即
parent 。相反,我们必须引用脚本(其中包含
addUrn
方法),同时调用该方法,因此在评级内调用addUrn
时使用this
。或者,您可以将“评级”发送到类似于addUrn
的方法。 - 括号、链括号和方括号的使用和顺序对于您在“元数据”之后看到的内容很重要。在这里理解这一点会很麻烦。但唯一需要注意的是坚持使用方法调用、声明列表和使用闭包的基础知识。尝试缩进每行的每个大括号,您将能够捕获底层的魔力。 :)
- StackOverFlow 错误的原因是
getEpisode
方法无法访问脚本拥有的addUrn
方法。
直接在Groovy Web Console中测试一下
关于json - 使用 Groovy JsonBuilder 设置委托(delegate)值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17355304/