I’ve just spent a little too much time trying to get my favicon working properly on a new grails application.
The issue I encountered was due to the fact that I wanted users to be able to access their accounts using ‘/[username]‘ – i.e. /paul
To accomodate this, I used a UrlMapping:
"/$id" {
controller='display'
action:'index'
}
Now, this meant that /favicon.ico would hit the controller, and not server the icon file. I first thought I could get around this by constraining the above mapping – so I tried:
"/$id" {
controller='display'
action:'index'
constraints {
id(notEqual:'favicon.ico')
}
}
It seems though that the only constraint you can use is ‘matches’. At least ‘notEqual’ resulted in a compile error, and all of the examples use ‘matches’.
So I thought I’d use matches with a regular expression of to exclude the word ‘favicon.ico’ – turns out that matching a word is simple, but negating it is not – I couldn’t find an expression to negate a word.
Anyway, I’ve noticed that when requesting ‘/favicon.ico’, the $id parameter resolves to ‘favicon’ – the extension has been stripped off! Luckily I stumbled across a forum post pointing me to the Content Negotiation section of the user guide. You can turn off this behaviour with
grails.mime.file.extensions = false
Luckily for me I’d restricted usernames with the constraint
matches:"[a-zA-Z0-9_-]+"
So now, I can use the same constraint on the controller:
"/$id" {
controller='display'
action:'index'
constraints {
id(matches:/[a-zA-Z0-9_-]+/)
}
}
Since the request for ‘/favicon.ico’ contains a dot, it fails this constraint and the controller no longer handles the request.
I wish I’d come to this conclusion more quickly (I also investigated what I could do on the Apache side of things, but didn’t get anywhere), but I’m glad I’ve learnt what I’ve learnt.
Note, you don’t necessarily need to do this – you can use the following code to specify an alternate url to the icon:
<link rel="shortcut icon" href="/common/apps/op/favicon.ico" type="image/x-icon" />






{ 3 comments… read them below or add one }
Thanks for posting your experience. It was very helpful!
Hey Paul, this might work. A regular expression to negate the favicon.ico:
/[(favicon.ico)]{11}/
OOOOPS……
adding ^ for NOT
/[^(favicon.ico)]{11}/