我正在尝试编写一个应始终使用JSON响应的Grails REST控制器.控制器如下所示:
class TimelineController {
static allowedMethods = [index: "GET"]
static responseFormats = ['json']
TimelineService timelineService
def index(TimeLineCommand command) {
List<TimelineItem> timeline = timelineService.currentUserTimeline(command)
respond timeline
}
}
Run Code Online (Sandbox Code Playgroud)
我使用的respond方法是Grails的REST支持的一部分,因此内容协商用于确定要呈现的响应类型.在这种特殊情况下,我希望选择JSON,因为控制器指定
static responseFormats = ['json']
Run Code Online (Sandbox Code Playgroud)
此外,我已经编写了(并在Spring中注册)以下渲染器来自定义为其返回的JSON格式 List<TimelineItem>
class TimelineRenderer implements ContainerRenderer<List, TimelineItem> {
@Override
Class<List> getTargetType() {
List
}
@Override
Class<TimelineItem> getComponentType() {
TimelineItem
}
@Override
void render(List timeline, RenderContext context) {
context.contentType = MimeType.JSON.name
def builder = new JsonBuilder()
builder.call(
[items: timeline.collect { TimelineItem timelineItem ->
def domainInstance = timelineItem.item
return [
date: timelineItem.date,
type: domainInstance.class.simpleName,
item: [
id : domainInstance.id,
value: domainInstance.toString()
]
]
}]
)
builder.writeTo(context.writer)
}
@Override
MimeType[] getMimeTypes() {
[MimeType.JSON] as MimeType[]
}
}
Run Code Online (Sandbox Code Playgroud)
我已经编写了一些功能测试,并且可以看到虽然我的渲染器被调用,但解析的内容类型是text/html,因此控制器返回404,因为它找不到具有预期名称的GSP.
我强烈怀疑这个问题与使用自定义渲染器有关,因为我有另一个几乎相同的控制器,它不使用自定义渲染器,它正确地解析了内容类型.
看起来你必须创建一个空白的(至少)index.gsp下
grails-app/views/timeline/
Run Code Online (Sandbox Code Playgroud)
使渲染器工作.我成功地取回了内容类型application/json
这种行为让我感到困惑,我仍然在研究它.这值得JIRA问题.如果你需要我可以将我的虚拟应用程序推送到github.
更新:
在github中创建的问题(带有示例应用程序的链接).
https://github.com/grails/grails-core/issues/716
小智 0
在Config.groovy中,grails.mime.types需要指定。详细信息可以在这里找到:Grails 2.3.11 Content Negotiation。至少你需要在 Config.groovy 中有以下内容:
grails.mime.types = [
json: ['application/json', 'text/json']
]
Run Code Online (Sandbox Code Playgroud)如果您想使用自定义 JSON 进行响应,render someMap as JSON建议使用。
response.setContentType('application/json')关于您的 404 问题,您需要在控制器操作中执行操作。Grails 的默认响应格式是 html,因此如果未指定 contentType,它将查找要呈现的 gsp 文件。