`
leon1509
  • 浏览: 533259 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Grails渲染JSON迷你手册

阅读更多
http://memo.feedlr.com/?p=6

Mini guide to rendering JSON with Grails

Grails has built-in support for a JSON building DSL, which, together with the render controller dynamic method, makes rendering JSON responses an enjoyable job. But there seems to be a lack of consolidated information in the official documentation to clarify all the bits about getting anything you want in JSON. So here’s my little mini guide to share with you.

Ground Rules
As the JSON spec reads,

JSON is built on two structures:

A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
So there are only two rules for rendering JSON with Grails.

1. To render a collection of name/value pairs (an object), use the method call syntax.

e.g.

render(contentType:'text/json'){
pair(name:'value')
}
Will be rendered as

{"pair":{"name":"value"}}
2. To render an array of values, use a closure

e.g.

render(contentType:'text/json'){
collection{
pair(name:'value')
pair(name:'value1')
}
}
Will be rendered as

{collection:[{"name":"value"},{"name":"value1"}]}
Anything inside the collection closure becomes the values of the array. And because of this, the method name “pair” has no place to appear in the rendered array.

Putting It to Work
Here’s an example putting the two rules together.

render(contentType:'text/json'){
studio(name:'Pixar',website:'pixar.com')
films{
film(title:'Toy Story',year:'1995')
film(title:'Monsters, Inc.',year:'2001')
film(title:'Finding Nemo',year:'2003')
}
}
The result JSON will be

{"studio":{"name":"Pixar","website":"pixar.com"},
"films":[
{"title":"Toy Story","year":"1995"},
{"title":"Monsters, Inc.","year":"2001"},
{"title":"Finding Nemo","year":"2003"}
]}
When DSL is Not Enough
But there’s a gotcha about the current JSON Builder DSL to keep in mind. As of 1.0 RC3, You can have objects inside an array, but not an array inside an object (except the JSON object itself).

For example, I want a JSON structure like this.

{"object":{"collection":[{"name":"value1"},{"name":"value2"}]}}
I may write something like this,

render(contentType:'text/json'){
object(collection{
item(name:'value1')
item(name:'value2')
})
}
Although it’s syntactically correct, you will get a runtime exception of

java.lang.IllegalArgumentException: JSON Builder: not implemented
at grails.util.JSonBuilder.createNode(JSonBuilder.java:121)
...
Oh, maybe I made a mistake, I think. The closure is not a key/value pair there. And I change the code like this

render(contentType:'text/json'){
object(collection:{
item(name:'value1')
item(name:'value2')
})
}
This looks better. Does it work? Nope. It’s not what you’d expect.

{"object":{"collection":"DummyController$_closure15_closure27_closure28@4af40c"}}
This can’t be right. Then how about

render(contentType:'text/json'){
object(collection:collection{
item(name:'value1')
item(name:'value2')
})
}
Oddly, this will be rendered as

{"collection":[{"name":"value1"},{"name":"value2"}],"object":{"collection":1}}
The Almighty JSON converter
So is there any workaround, when JSON Builder DSL fails you? Yes! You can always turn to the JSON converter. Construct a temporary Map to contain the data, and use the converter to render the map as a whole.

To correctly render the JSON data in the previous section, you can use the JSON converter this way. In your controller, use the following code.

import grails.converters.*
...
def jsonMethod = {
...
def json = [object:[collection:[[name:'value1'],[name:'value2']]]]
render json as JSON
}
The result JSON will be exactly what I want

{"object":{"collection":[{"name":"value1"},{"name":"value2"}]}}
You can render any object using the JSON converter. And the results are pretty predictable.

Performance-wise, I’m not sure if there’s any difference or anyone has done any benchmark yet. So I’d say that it’s really your call which way to make your JSON. The converter doesn’t look as sexy as the DSL, but it sure works great. I may just choose either one depending on my mood:)

Tags: dsl, Grails, javascript, json

This entry was posted on Sunday, January 13th, 2008 at 4:11 pm and is filed under Grails. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

Login
Add New Comment

Post as …
Showing 9 comments
Sort by      Subscribe by email    Subscribe by RSS

Suejo75 1 week ago
How can i read a Json file generated by grails? When i do this my application ask me if i want to open it or down load so anybody can help me?
Like  Reply

Merrick BeforeBuffaloDogFood 1 month ago
It is good, I think it is helpful.
Like  Reply

Horses For Sale 1 month ago
The "render as JSON" is an excellent workaround and allows for nice refactoring of business logic into services so controller methods simply invoke service calls and render the resulting map.
Like  Reply

verunchik 5 months ago
Hallo, can you help me to make this json text:
I need: {"Result":[{"assets":["aaa", "bbb"]},...
but I have: {"Result":[{"assets":"[aaa, bbb]"},...
My code is:
render(contentType:"text/json") {
Result {pair(assets: links)
}}
links is array ["aaa", "bbb"]
Thanks!
Like  Reply

Guest 8 months ago
Hi, nice to meet you, my site provide DSL service, i hope you can get some information interesting in my site
Like  Reply

Noels 9 months ago
Thanks for the excellent article. That has helped me a great deal. Do you happen to know how I can get an anonymous collection like this: [{"name":"value"},{"name":"value1"}] ?
Like  Reply

modestymaster 6 months ago in reply to Noels
Using the builder example above, you may want to consider something like this:

def fakeJSON = []
listOfStuff.each {
fakeJSON.add(["name":it.text()])
}
render fakeJSON as JSON
分享到:
评论

相关推荐

    Grails1.3.7参考手册

    Grails 1.3.7英文版官方参考手册,学习Grails的权威指南

    grails-用户手册

    《Grails用户手册》 Grails,作为一个基于Groovy语言的开源Web应用框架,深受开发者喜爱,它简化了Java开发的复杂性,提供了强大的MVC(Model-View-Controller)架构,以及丰富的插件系统。这份用户手册将帮助你...

    Grails超全操作手册(中文版)

    Grails超全中文操作手册,无论是大神还是初学者都很适用的操作文档。很全很详细,希望能帮到学习grails框架的你。

    Grails中文参考手册

    "Grails 中文参考手册" 是一套详细的 Grails 学习资料,涵盖了框架的所有核心组件、最佳实践和使用方法,帮助开发者快速掌握 Grails 开发技能。 总之,Grails 是一个强大而灵活的 Web 开发框架,结合 Groovy 的优点...

    Grails-2.4.4-用户手册

    **Grails 2.4.4 用户手册** **一、Grails 框架概述** Grails 是一个基于 Groovy 语言的开源全栈式Web应用框架,它旨在提高开发效率,提供简洁、灵活的代码结构,以及强大的自动化工具。Grails 2.4.4 是该框架的一个...

    精通Grails 之用 JSON 和Ajax 实现异步Grails(pdf电子书)

    ### 精通Grails之用JSON和Ajax实现异步Grails #### 一、引言 随着Web 2.0技术的发展,JSON (JavaScript Object Notation) 和 Ajax (Asynchronous JavaScript + XML) 成为现代Web应用开发的重要组成部分。本文旨在...

    grails 1.0 英文操作手册

    ### Grails 1.0:敏捷、工业级的快速Web应用开发框架 #### 引言 Grails 1.0框架旨在提供一个敏捷且强大的工具集,用于加速Web应用程序的开发过程。它融合了Groovy语言的灵活性与Spring框架的强大功能,以及...

    grails中文使用手册

    4. **Grails插件**:Grails生态系统中的插件极大地扩展了框架的功能,如Spring Security用于安全控制,GSP(Grails Server Pages)用于视图渲染,以及CouchDB或MongoDB插件实现NoSQL数据库的支持。 5. **...

    Grails 中文参考手册

    《Grails 中文参考手册》是一本全面介绍Grails框架的指南,旨在帮助开发者快速上手并深入理解Grails的各个核心概念和技术。Grails是一个基于Groovy语言的开源Web应用框架,它提供了高效的开发环境和强大的功能,使得...

    Grails+groovy 完整参考手册.7z

    通过阅读《Grails+groovy 完整参考手册.docx》,你可以更深入地了解这两个技术,包括它们的原理、最佳实践以及实际应用中的案例。无论你是初学者还是有经验的开发者,这份手册都将是你学习和提升技能的宝贵资源。

    Grails 1.1 中文手册 chm

    Grails 最新的 v1.1版的中文文档,chm格式,Grails是一套快速开发Web应用的开源框架,基于Groovy编程语言,并构建于Spring、Hibernate和其它标准Java框架之上,能为大家带来超高效率的一站式框架。

    grails 中文手册

    **Grails 框架详解** Grails 是一个基于 Groovy 语言的开源Web应用程序框架,它构建在Java平台之...通过阅读《Grails 中文手册》,开发者可以深入理解框架的工作原理,掌握各种开发技巧,从而提高开发效率和代码质量。

    Grails安装SVN客户端插件指导手册

    在IT行业中,Grails是一个基于Groovy语言的开源Web应用框架,它简化了Java平台上的开发流程。在Grails项目中,版本控制是至关重要的,而Subversion(SVN)是一种常用的版本控制系统,用于管理软件项目的源代码。为了...

    Grails中文手册

    Grails开发中文手册,让你学的更轻松!~

    Grails Grails Grails

    **Grails 框架详解** Grails 是一个基于 Groovy 语言的开源Web应用程序框架,它构建在Java平台之上,旨在简化开发过程并提高生产力。Grails 的设计深受Ruby on Rails的影响,提供了MVC(模型-视图-控制器)架构模式...

    grails和flex的集成手册

    这通常涉及到将UI渲染的工作卸载到客户端机器上。 - **利用Flex的Rich UI能力**:Flex通过其MXML语言定义用户界面,并使用ActionScript作为编程语言。这样可以轻松创建具有丰富表现力的用户界面。 - **示例分析**:...

Global site tag (gtag.js) - Google Analytics