我最近在我的一个项目中使用了JsonBuilder ,最初在理解其运行方式时遇到了一些困难。 我的假设是JsonBuilder的工作方式与MarkupBuilder相似,但是正如我很快发现的那样,事实并非如此。
让我们举一个简单的例子。 假设我们有一个Message类,我们想序列化为XML标记和JSON。
@groovy.transform.Canonical
class Message {
long id
String sender
String text
}
assert 'Message(23, me, some text)' ==
new Message( 23, 'me', 'some text' ).toString()
在这里,我使用了Groovy 1.8.0 @Canonical批注, 该批注提供了自动toString() , equals()和hashCode()以及一个元组(有序的)构造函数 。
让我们将许多消息序列化为XML。
def messages = [ new Message( 23, 'me', 'some text' ),
new Message( 24, 'me', 'some other text' ),
new Message( 25, 'me', 'same text' )]
def writer = new StringWriter()
def xml = new groovy.xml.MarkupBuilder( writer )
xml.messages() {
messages.each { Message m -> message( id : m.id,
sender : m.sender,
text : m.text )}
}
assert writer.toString() == """
<messages>
<message id='23' sender='me' text='some text' />
<message id='24' sender='me' text='some other text' />
<message id='25' sender='me' text='same text' />
</messages>""".trim()
好吧,那很简单。 让我们尝试对JSON做同样的事情。
def json = new groovy.json.JsonBuilder()
json.messages() {
messages.each { Message m -> message( id : m.id,
sender : m.sender,
text : m.text )}
}
assert json.toString() ==
'{"messages":{"message":{"id":25,"sender":"me","text":"same text"}}}'
哇,其他所有消息都到哪里去了? 为什么列表中只有最后一条消息被序列化?
这个怎么样:
json = new groovy.json.JsonBuilder()
json.messages() {
message {
id 23
sender 'me'
text 'some text'
}
message {
id 24
sender 'me'
text 'some other text'
}
}
assert json.toString() ==
'{"messages":{"message":{"id":24,"sender":"me","text":"some other text"}}}'
相同的故事。 最初我很困惑,但是后来JsonBuilder 源代码显示每次调用都覆盖了先前的内容:
JsonBuilder(content = null) {
this.content = content
}
def call(Map m) {
this.content = m
return content
}
def call(List l) {
this.content = l
return content
}
def call(Object... args) {
this.content = args.toList()
return this.content
}
def call(Closure c) {
this.content = JsonDelegate.cloneDelegateAndGetContent(c)
return content
}
如您所见,应该只调用一次JsonBuilder ,然后将其传递给Map , List ,varargs或Closure 。 这使得JsonBuilder从MarkupBuilder的 ,可以多次根据需要进行更新非常不同。 它可以由JSON本身,其格式与自由格式的XML标记严格造成的:东西开始作为一个JSON地图的单一信息 ,不能制作成消息的阵列出突然。
也可以在构造函数中指定传递给JsonBuilder的参数(Map,List,varargs或Closure),因此根本不需要调用构建器。 您可以简单地使用相应的数据结构对其进行初始化,然后立即调用toString() 。 让我们试试吧!
def listOfMaps = messages.collect{
Message m -> [ id : m.id,
sender : m.sender,
text : m.text ]}
assert new groovy.json.JsonBuilder( listOfMaps ).toString() ==
'''[{"id":23,"sender":"me","text":"some text"},
{"id":24,"sender":"me","text":"some other text"},
{"id":25,"sender":"me","text":"same text"}]'''.
readLines()*.trim().join()
现在它可以工作了:)将消息列表转换为Maps列表并将它们一次性发送到JsonBuilder之后,生成的String包含列表中的所有消息。 上面的所有代码都可以在Groovy Web控制台中找到,因此欢迎您尝试一下。
顺便说一句,为了在线查看JSON,我推荐Chris Nielsen开发的出色的“ JSON Visualization ”应用程序。 “ Online JSON Viewer ”是另一个受欢迎的选项,但是我更喜欢第一个。 对于离线使用,“ JSON Viewer ”是一个很好的Fiddler插件。
聚苯乙烯
如果您需要通过发送例如Ajax GET请求在客户端读取此JSON,则可以使用jQuery.get()轻松完成此操作:
<script type="text/javascript">
var j = jQuery;
j( function() {
j.get( 'url',
{ timestamp: new Date().getTime() },
function ( messages ){
j.each( messages, function( index, m ) {
alert( "[" + m.id + "][" + m.sender + "][" + m.text + "]" );
});
},
'json'
);
});
</script>
在这里,我使用j快捷键的巧妙技巧来避免在不使用$的情况下多次键入jQuery 。
参考: Groovy 1.8.0 –满足JsonBuilder! 来自我们的JCG合作伙伴 Evgeny Goldin在Goldin ++博客上。
翻译自: https://www.javacodegeeks.com/2012/03/groovy-180-meet-jsonbuilder.html
本文介绍了在Groovy 1.8.0中使用JsonBuilder时遇到的序列化问题,通过示例展示了如何正确地将数据转化为JSON格式,强调了JsonBuilder的使用方式与MarkupBuilder的不同,特别是JsonBuilder需要一次性传递所有数据。同时推荐了用于查看JSON的在线工具,并提供了一个使用jQuery获取JSON数据的Ajax示例。



被折叠的 条评论
为什么被折叠?



