Grails - add header to every response

12,082

To simply add a header to the response, you can use an after Filter.

// grails-app/conf/MyFilters.groovy
class MyFilters {
    def filters = {
        addHeader(uri: '/*') {
            after = {
                response.setHeader('X-Time', value)
            }
        }
    }
}

Edit:

To actually compute the time, it'd probably be more proper to use a javax.servlet.Filter instead of a Grails filter.

src/groovy/com/example/myproject/MyFilter.groovy

package com.example.myproject

import javax.servlet.*

class MyFilter implements Filter {

    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {

        def start = System.currentTimeMillis()
        chain.doFilter(request, response)

        def elapsed = System.currentTimeMillis() - start
        response.setHeader('X-Time', elapsed as String)
    }

    void init(FilterConfig config) { }
    void destroy() { }
}

src/templates/war/web.xml (run grails install-templates if src/templates isn't already in your source tree)

<filter>
  <filter-name>timer</filter-name>
  <filter-class>com.example.myproject.MyFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>timer</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

The reason for using the javax.servlet.Filter is so you don't have to separate out your "before" and "after" actions, and can therefore hold onto the start time throughout the entire filter chain & servlet execution.

Supplementary note:

To me, it seems strange to want to return the server elapsed execution time as a response header. Perhaps you have a decent reason for doing it, but in most cases I'd A) either be more concerned about total round-trip time (as observed by the client), or B) be logging elapsed execution times on the server for my own system administration/metrics purposes.

Share:
12,082
BuddyJoe
Author by

BuddyJoe

I like to code C# and work with the web. Still learning.

Updated on June 04, 2022

Comments

  • BuddyJoe
    BuddyJoe almost 2 years

    How could I add a response header - say X-Time that would look something like:

    X-Time: 112

    Where the value given would be the time in milliseconds that the response took to process? Is there a really simple way to add this to an Grails app? Not something I want to leave on permanently but would be nice to have while developing my app.

  • BuddyJoe
    BuddyJoe almost 13 years
    I guess that could work... How could I start the timer? and end it? I could start a timer in a before filter but how would I get that value to the after filter? Good idea so far +1
  • Rob Hruska
    Rob Hruska almost 13 years
    I guess I only interpreted your question as asking how you would add the response header; let me build up a quick answer for actually timing it.
  • BuddyJoe
    BuddyJoe almost 13 years
    Looks awesome. Thanks. +1 and answer. I just have a system where a client can report performance problems. And it includes timing the complete request/response time from the client. But also includes the actual "work time" / performance of the server.
  • Rob Hruska
    Rob Hruska almost 13 years
    @tyndall - An understandable use case :) - glad it worked for you.
  • Robert
    Robert about 12 years
    Note that if you want to add some header that does not depend on the processing pipeline (e.g. not the timing) then you can set the header in the before closure rather than the after closure (or in the pre-processing of the Servlet Filter). That way you don't encounter errors with responses that have been closed.