Grails REST控制器响应不正确的内容类型

Dón*_*nal 12 rest grails

我正在尝试编写一个应始终使用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.

我强烈怀疑这个问题与使用自定义渲染器有关,因为我有另一个几乎相同的控制器,它不使用自定义渲染器,它正确地解析了内容类型.

dma*_*tro 6

看起来你必须创建一个空白的(至少)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

  1. 在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)
  2. 如果您想使用自定义 JSON 进行响应,render someMap as JSON建议使用。

  3. response.setContentType('application/json')关于您的 404 问题,您需要在控制器操作中执行操作。Grails 的默认响应格式是 html,因此如果未指定 contentType,它将查找要呈现的 gsp 文件。