Grails 2 - 自动生成 JSON 输出(就像 Spring 3.x 一样)
Posted
技术标签:
【中文标题】Grails 2 - 自动生成 JSON 输出(就像 Spring 3.x 一样)【英文标题】:Grails 2 - produce JSON output automatically (like Spring 3.x does) 【发布时间】:2012-08-06 06:35:15 【问题描述】:在 Spring MVC 3.x 中,我可以配置一个 ContentNegotiatingViewResolver
bean 来自动以 JSON 或 XML 格式呈现任何给定的端点,只需将文件扩展名更改为 .json
或 .xml
。我以为 Grails 中有一个等效的功能,但我找不到。
我读过的所有内容都说我必须捕获传入的 mime 类型(使用 withFormat
),然后在我的每个控制器方法中使用 render as JSON
(或等效项)指定 JSON 输出(例如 rendering JSON with Grails? )。在我开始向我的控制器添加特定于 JSON 的代码之前,我想我会在这里问...
所以我的问题是:我能否通过简单地为任何给定 URL 添加一个 `.json' 文件扩展名(或更改接受标头)来配置 Grails 2 以自动生成 JSON 输出?
【问题讨论】:
如果你还在使用脚手架,你可以把它添加到脚手架上,它会应用到你所有的控制器上。 【参考方案1】:我认为您可以使用 grails filter 轻松访问它
这是我在我的应用程序中通过 OAuth API 完成的过滤器,它基于接受标头执行 xml、json 和 yalm
class RenderFilters
def grailsApplication
def filters =
multiFormat(controller: '*EndPoint', action: '*', search: true)
after = Map model ->
def accepts = request.getHeaders('accept')*.toLowerCase()
def out = model.containsKey('out')?model.out:model
if(accepts.any it.contains('json') )
render(text: out as JSON, contentType: 'application/json', encoding:"UTF-8")
else if(accepts.any it.contains('yaml') )
render(text: Yaml.dump(out), contentType: 'application/x-yaml;', encoding:"UTF-8")
else if(accepts.any it.contains('html') )
render(text: out as JSON, contentType: 'application/json', encoding:"UTF-8")
else if(accepts.any it.contains('xml') )
render(text: out as XML, contentType: 'application/xml', encoding:"UTF-8")
else
render(text: out as JSON, contentType: 'application/json', encoding:"UTF-8")
false
before =
def contentType = request.getHeader('Content-Type')?.toLowerCase()
if(!contentType) return true
if(contentType == 'application/json')
params.body = JSON.parse(request.reader)
if(contentType == 'application/xml')
params.body = XML.parse(request.reader)
if(contentType == 'application/x-yaml')
params.body = Yaml.load(request.reader)
params.body = new TypeConvertingMap((Map) params.body)
true
【讨论】:
这看起来像是要走的路。在接受正确之前,我会在星期一试一试。它甚至具有允许我添加 JSONP 回调包装器的优势!【参考方案2】:对于遇到这个 SO 问题的任何人,我想我会包含我的最终 Grails(版本 2.x)过滤器代码,因为它与 F***o 的回答(上图)中的代码确实不同。
以下过滤器允许 Grails 正常处理纯 HTML 内容,并使用 Grails 内容协商机制通过文件扩展名或接受标头设置 response.format
(取决于 conf 设置:grails.mime.use.accept.header
& grails.mime.file.extensions
)。我还添加了对 JSONP 回调包装器的支持。
import grails.converters.JSON
import grails.converters.XML
class RenderFilters
def filters =
multiFormat(controller: '*', action: '*', find: true)
after = Map model ->
def out = model?.containsKey('out')?model.out:model
if (response.format == "json" && params.callback)
render(text: params.callback + "($out as JSON)" , contentType: 'application/javascript', encoding:"UTF-8")
false
else if (response.format == "json")
render(text: out as JSON, contentType: 'application/json', encoding:"UTF-8")
false
else if (response.format == "xml")
render(text: out as XML, contentType: 'application/xml', encoding:"UTF-8")
false
【讨论】:
【参考方案3】:我偶然发现最新的 grails 通过简单地在查询中设置 Accept 标头就可以自动输出 JSON 和 XML!
我目前使用的是 2.3.2,但可能与早期版本相同,我只是创建了一个新应用程序,创建了一个具有一些属性的新简单域类,运行 generate-all 然后运行应用程序。运行后, curl -i -H "Accept: application/json" 返回 JSON, curl -i -H "Accept: application/xml" 返回 XML,无需任何额外工作。
我对此感到非常惊讶,为了确保我没有在我的本地机器上安装奇怪的东西,我在安装了新 grails 的全新服务器上尝试了它......它可以工作!!!
【讨论】:
以上是关于Grails 2 - 自动生成 JSON 输出(就像 Spring 3.x 一样)的主要内容,如果未能解决你的问题,请参考以下文章
Grails 无法将 JSON 中的日期/时间解组回 joda DateTime