我想使用Grails中的JSON渲染方法渲染复杂类型,类似于下面的JSON输出:
{"authors":[{"id":1,"name":"Author 1","books":[{"id":1,"name":"Book 1"},{"id":2,"name":"Book 2"}]},{"id":2,"name":"Author 2","books":[{"id":1,"name":"Book 1"},{"id":2,"name":"Book 2"}]}]}
我尝试使用以下代码执行此操作,其中Author和Book是包含属性id和name以及Author hasMany Books(association)的域类.
def results = Authors.list() render(contentType:"text/json") { authors = array { for(a in results) { author id:a.id, name:a.name, books: array = { def bookresults = Book.findAllByAuthor(a) for(b in bookresults) { book id:b.id, name:b.name } } } } }
它仅适用于作者,但是当我尝试遍历每个作者的书籍并渲染它们时,代码就会失败.
有任何想法吗?
最终代码更新了问题
感谢Dave的回答,我最终得到了以下代码,它按预期工作:
def authors = [] for (a in Author.list()) { def books = [] def author = [id:a.id, name:a.name, books:books] for (b in Book.findAllByAuthor(a)) { def book = [id:b.id, name:b.name] books << book } authors << author } def items = [authors:[authors]] render items as JSON
Dave Bower.. 10
我发现JSON构建器很难用于获得所需的结果,所以我更喜欢在地图和列表中生成结果然后渲染它们.
通过具有以下内容(警告:未经测试的代码!):
def results = [] Authors.list()?.each{ author -> def authorResult = [id:author.id, name:author.name] Book.findAllByAuthor(author)?.each { book -> authorResultput('books', [id:book.id, name:book.name]) } results << authorResult } def authors = [authors: results] render authors as JSON
我认为你使代码更容易阅读和重用,它应该做你想要的(我的错别字允许).
如果你总是会呈现你在同一个JSON格式作者和图书的你可以考虑注册BootStrap.groovy中的自定义JSON对象编组.总之类似的工作:
JSON.registerObjectMarshaller(Author) { def returnArray = [:] returnArray['id'] = it.id returnArray['name'] = it.name return returnArray }
在作者身上拥有书籍属性也会让事情变得更容易!
我发现JSON构建器很难用于获得所需的结果,所以我更喜欢在地图和列表中生成结果然后渲染它们.
通过具有以下内容(警告:未经测试的代码!):
def results = [] Authors.list()?.each{ author -> def authorResult = [id:author.id, name:author.name] Book.findAllByAuthor(author)?.each { book -> authorResultput('books', [id:book.id, name:book.name]) } results << authorResult } def authors = [authors: results] render authors as JSON
我认为你使代码更容易阅读和重用,它应该做你想要的(我的错别字允许).
如果你总是会呈现你在同一个JSON格式作者和图书的你可以考虑注册BootStrap.groovy中的自定义JSON对象编组.总之类似的工作:
JSON.registerObjectMarshaller(Author) { def returnArray = [:] returnArray['id'] = it.id returnArray['name'] = it.name return returnArray }
在作者身上拥有书籍属性也会让事情变得更容易!