Blazerg
Blazerg

Reputation: 849

Add a response header on every request in a grails 3 incterceptor

I want to add this custom header to every response on my rest API:

"customHeader": "foo"

For this, I have created a grails interceptor that matches every controller and allows me to modify the request.

class FooInterceptor {

    FooInterceptor() {
        matchAll()
    }

    boolean before() { true }

    boolean after() {
        header 'customHeader', "foo" //first try
        response.addHeader 'customHeader', "foo" //second try to do the same
        response.setHeader 'customHeader', "foo" //third try, setHeader doesn't work either
        true
    }

    void afterView() {
    }
}

I have debugged and I can see that the after method is called after the controller respond:

respond([status:dodes.OK], [:])

I can see clearly that my interceptor is called and the addHader is not throwing any exception but my header is just not added to the final response.

My guess here is that maybe the grail's respond method somehow "locks" the response so the header can't be added after but I am not sure.

How can I add a header to every response on grails 3 using an interceptor?

Upvotes: 6

Views: 1631

Answers (2)

Radu-Stefan Zugravu
Radu-Stefan Zugravu

Reputation: 99

In one of my projects I use setHeader instead of addHeader and it works.

You can try this:

class FooInterceptor {

    FooInterceptor() {
        matchAll()
    }

    boolean before() { true }

    boolean after() {
        response.setHeader('customHeader', 'foo')
        true
    }

    void afterView() {
    }
}

The response object is an instance of the Servlet API’s HttpServletResponse class. Reading the documentation I see that both methods are available. The difference is that with addHeader you can add multiple values to a particular header, whereas an initial value would be overwritten if you use the setHeader method.

You can read more about it here: https://docs.grails.org/3.3.9/ref/Controllers/response.html

Upvotes: 2

dre
dre

Reputation: 1037

The following works for me. You may need to use before() instead.

class FooInterceptor {

    FooInterceptor() {
        match controller: '*', action: '*'
    }

    boolean before() {
        response.setHeader('customHeader', "foo") 
        true
    }

    boolean after() { true }

    void afterView() {
      // no-op
    }
}

Upvotes: 1

Related Questions