Nick De Greek
Nick De Greek

Reputation: 1894

Grails doesn't add headers for json

I'm trying to add custom headers using filters on a test grails app. I've setup a filter like this:

class MyFilters {
    def filters = {
        addHeader(uri: '/*') {
            after = { Map model ->
                response.setHeader('X-Test-Header', '123')
            }
        }
    }
}

If I try to access the controller and inspect the headers:

curl -I -H "Accept: text/html" -X GET 'http://localhost:8080/Test1/doSomething'

then, I get the additional header: X-Test-Header: 123 but if I try the above curl using "Accept: application/json" I get the content as JSON but I don't get any additional header.

What am I doing wrong?

I forgot to mention that I'm experimenting with the new grails REST functionality and my controller extends RestfulController

EDIT: I've done some additional experiments. I've added another filter as groovy class and modified the web.xml (got the idea from this article - grails-add-header-to-every-response and it does not work for application/json but does work for text/html! Is it possible that extending the RestfulController bypasses the standard filters?

EDIT2: It appears that adding headers works for application/xml and text/xml but not for application/json and text/json. The more I look at it, it appears as a bug and not that I'm doing something wrong because I see exactly the same behavior on a brand new project on a brand new VM (in case my dev machine has some sort of strange configuration). I'll create a bug report on JIRA

EDIT3: Opened a JIRA case and when I know more, I'll update this task

EDIT4: Based on the JIRA case, it appears that it is a bug and it'll be corrected on grails 2.3.4

Upvotes: 1

Views: 1119

Answers (1)

Nick De Greek
Nick De Greek

Reputation: 1894

Opened a JIRA case. It appears that the "after" action allows modification of the model before rendering the view but the respond method renders the JSON and executes the "after" action after outputing the response (so, it's too late to modify the response). So, according to Graeme Rocher, a workaround is to add the headers in the "before" block or in the action as follows:

def index(Integer max) {
    params.max = Math.min(max ?: 10, 100)
    response.setHeader('X-MyHeader', '123')
    respond Person.list(params), model:[personInstanceCount: Person.count()]
}

So, this will correct the behavior of the index action

Upvotes: 2

Related Questions