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.
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
In Config.groovy, grails.mime.types
needs to be specified. The details could be found out here: Grails 2.3.11 Content Negotiation . At least you need to have the following in Config.groovy:
grails.mime.types = [ json: ['application/json', 'text/json'] ]
If you want to respond with customized JSON, render someMap as JSON
is recommended.
About your 404 problem, you need to do response.setContentType('application/json')
in your controller action. Grails' default response format is html, so that it will look for the gsp file to render if the contentType is not specified.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.