Enhance HttpServletRequest using metaprogramming

25 / Sep / 2012 by Bhagwat Kumar 1 comments

Most of the times we use request.getHeader("user-agent") to get the client browser user-agent details inside the Grails Filters or Controllers. User-agent is one of the examples. There are so many such methods e.g. method for checking whether the request was an ajax call, getting IP address of the client machine, checking whether the request is made by a mobile browser etc. Lets create a class with a static method (create file in grails-app/src source folder) :

import javax.servlet.http.HttpServletRequest

class HttpRequestMetaClassEnhancer{
  public static void enhanceRequest(){
    HttpServletRequest.metaClass {
       getRemoteIPAddress = {
           delegate.getHeader("x-forwarded-for") ?: delegate.remoteAddr
       isAjax = {
           delegate.getHeader("X-Requested-With") == "XMLHttpRequest"
       getSiteUrl = {
           delegate.scheme + "://" + delegate.serverName + ":" + delegate.serverPort + delegate.getContextPath()
       getUserAgent = {
       isMobileBrowser = {
              Keep adding methods that are common to projects as comment to blog.
              I will update this blog with your helper methods

In most of the projects, we use an inline plugin which adds our commonly used utility methods to respective groovy classes using groovy metaprogramming. Bootstrap.groovy is another place for adding dynamic behaviour to classes like HttpServletRequest so that it is ready before being used inside Grails Controllers/Filters etc. Just make a call to enahceRequest static method of HttpRequestMetaClassEnhancer class in init closure of Bootstrap.groovy file.

class Bootstrap{
    def init = { servletContext ->
    def destroy = {}

Now you can access properties like remoteIPAddress, ajax, siteUrl, userAgent, mobileBrowser etc. on request object in Grails Filters/Controllers. See below a sample filter which prints request related information on each request received to the server log.

class ApplicationFilters{
def filters = {
        logParams(controller: '*', action: '*') {
            before = {
                log.info "[IP: ${request.remoteIPAddress},"+
                           "url: ${params.controller}/${params.action},"+
                           "ajax: ${request.ajax},"+
                           "Mobile browser: ${request.mobileBrowser} ]:"+
                            params.findAll {!['password', 'passwd', 'controller', 'action'].contains(it.key)}

Or a sample controller :

class UtilController{
  def index(){
          render "You got a nice mobile. You are viewing : "+request.siteUrl
           request.ajax ? render(view:'index) : render(template :'tabularData')

Thanks to all the contributors whose helper methods has made this a long blog.


comments (1 “Enhance HttpServletRequest using metaprogramming”)

  1. cheap uggs

    To buy to buy UGG 2011 Fashion Style Tassels 9811 Chestnut clearance ,it`s UGG 2011 Fashion Style Tassels 9811 Chestnut Color: Chestnut Fahion style UGG genuine sheepskin sock that naturally wicks away moisture and helps keep your feet dry and cozy. Pure Genuine Australia woolen knitting yarn UGG boots soft suede and top sheep wool. Have a molded EVA light and flexible outsole designed for amazing comfort with every step.This style has to be specially made for 3-5 working days. at ugg boots clearance.


Leave a comment -