Grails catch all url mapping with exceptions
I am trying to create a mock rest service. There are basically two components to this. I need a controller with actions and views that allows me to create ResourceMappings where I create a mapping between a uri and a mock response that I will pass back. The second component is a catch-all Grails url mapping for every other url so that when they hit the uri of this application they will be sent to my catch all controller that will return the mapped response that they created earlier.
For example... I go to the url http://someserver.com:1234/restMapping/list. This url is the exception to the catch all rule. It takes me to some views that allow me to create a rest uri mapping. Here I create the mapping /mockservice/test and give it the response "This is a test" with a content type of text/plain. Now, if I go to the url http://someserver.com:1234/mockservice/test I should hit the catch all that sends me to a contr开发者_开发问答oller that returns a page with the content type text/plain and the response "This is a test".
I have tried the following and it does not seem to work. Does anyone have any ideas?
static mappings = {
"/$control/**" {
controller = "catchAllHandler"
action = "index"
constraints {
control(validator: {!['restMapping','css','js','images'].contains(it)})
}
}
"/$controller/$action?/$id?"{
}
"/"(controller:"restMapping", action="index")
"500"(view:'/error')
}
An interesting thing to note is that when I get rid of ** and add in tons of extra variables like $s1?/$s2?/$s3? etc then it does seem to work. The problem is that I don't know how long the uri is that I am trying to map so I would rather use the ** to catch everything exception the few exceptions that I have.
I finally figured it out. I needed to include WEB-INF in my list to exclude. I now use the static excludes field as well as the validator to exclude specific controller urls.
class UrlMappings {
static excludes = ["/images/*","/css/*","/js/*","/WEB-INF/*"]
static mappings = {
"/restResourceMapping/$action?/$id?"{
controller = "restMapping"
}
"/$control/?**" {
controller = "catchAllHandler"
action = "index"
constraints {
control(validator: {!['restMapping'].contains(it)})
}
}
"/"(controller:"restMapping", action="index")
"500"(view:'/error')
}
}
I decided to just exclude all url mappings that should never be any of my rest urls. These included /images, /css, /js, and /WEB-INF. I can now create urls of any length and have them go to my catch all controller. If the person goes to the base url or the restMapping url set then they will be taken to the crud pages where they can create new rest resource mappings. If I want to create any other controllers and views that I want to go around the catch all controller I can simply add it to my validator and make them process normally.
Also you might notice that I am using a ? in the catch all right after the /. This seems to make it so my catch all works with urls that only have one word after the server name as in http://server.com:1234/something.
I am not sure about this, but I think the order in which the URL mappings are defined is important. So try listing the URL mapping for your special cases at the beginning of the mappings closure and then list the general ones (the one that uses **). Do let me know if this works :)
精彩评论