grailsgroovyurlmappings.groovy

Logic block in Grails URLMappings


My site has urls like 'http://someRandomUsername.mysite.com'. Sometimes users will try urls like 'http://www.someRandomeUsername.mysite.com'. I'd like to have some logic in my url mappings to deal with this. With the mappings below when I hit the page , with or without the unneeded www, I get:

2012-03-01 14:52:16,014 [http-8080-5] ERROR [localhost].[/ambit] - Unhandled exception occurred whilst decorating page java.lang.IllegalArgumentException: URL mapping must either provide a controller or view name to map to!

Any idea how to accomplish this? The mapping is below.

Thanks! Jason

static mappings = {

         name publicMap: "/$action?/$id?" {
                 def ret = UrlMappings.check(request)
                 controller = ret.controller
                 userName = ret.userName
         }
}

static check =
{ request ->
         def tokens = request?.serverName?.split(/\./) as List ?: []
         def ret = [controller:'info']
         if(tokens.size() > 3 && token[0] == 'www')
         {
                 ret.userName = tokens[1]
                 ret.controller = 'redirect'
                 ret.action = 'removeWWW'
         }
         else if(tokens.size() == 3)
         {
                 ret.userName = tokens[0]
                 ret.controller = 'info'
         }

         return ret
}

Solution

  • Honestly, like DmitryB said, the best way to do this is via the web server, whether it's IIS, Apache, or Tomcat.

    Having said that, I feel the best way to accomplish this in Grails would be using filters. You could create something like this in your ~/conf directory:

    public class StripFilters {
      def filters = {
        stripWWWFilter(controller: '*', action: '*') {
          before = {
            def tokens = request.serverName.tokenize(/\./) ?: []
    
            if(tokens.size() > 3 && tokens[0] == 'www') {
              def url = request.request.requestURL.toString().replace('www.', '')
              redirect([url:url, params: [userName: tokens[1]], permanent: true])
              return false
            }
          }
        }
      }
    }
    

    This should do the trick.