Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails REST controller responds with incorrect content type

Tags:

rest

grails

I'm trying to write a Grails REST controller that should always respond with JSON. The controller is shown below:

class TimelineController {

    static allowedMethods = [index: "GET"]
    static responseFormats = ['json']

    TimelineService timelineService

    def index(TimeLineCommand command) {
        List<TimelineItem> timeline = timelineService.currentUserTimeline(command)
        respond timeline
    }
}

I'm using the respond method which is part of Grails' REST support, so content negotiation is used to figure out what type of response to render. In this particular case I would expect JSON to be chosen because the controller specifies

    static responseFormats = ['json']

Furthermore I've written (and registered with Spring) the following renderer to customise the format of the JSON that is returned for the 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[]
    }
}

I've written some functional tests, and can see that although my renderer is invoked, the resolved content type is text/html, so the controller returns a 404 because it can't find a GSP with the expected name.

I strongly suspect the problem is related to the use of a custom renderer, because I have another almost identical controller which doesn't use a custom renderer and it resolves the content type correctly.

like image 925
Dónal Avatar asked May 15 '15 16:05

Dónal


1 Answers

Looks like you have to create a blank (at least) index.gsp under

grails-app/views/timeline/

to make the renderer work. I am successfully getting back content type as application/json

This behavior baffles me a lot and I am still looking into it. This is worth a JIRA issue. If you need I can push my dummy app to github.

UPDATE:
Issue created in github (with links to sample app).
https://github.com/grails/grails-core/issues/716

like image 148
dmahapatro Avatar answered Sep 20 '22 05:09

dmahapatro