How can I use path variables in grails controller?

Vishal picture Vishal · Jul 2, 2014 · Viewed 7.3k times · Source

I have been trying to use a path variable in grails controller but I am not able to achieve it. The intention behind is to validate the parameter submitted to the url which I need to make mandatory. I could not achieve it through RequestParam so I switched to PathVariable so that the url submitted without the required param should be filtered off by grails controller itself rather than me adding if/else checks for validity.

So, I can illustrate as below: My URL is something as below:-

'<appcontext>/<controller>/<action>?<paramName>=<something>'

Now, to make 'paramName' mandatory I am not finding any way in Grails(Spring MVC provides @RequestParam annotation which can enable me for 'required' as true).

Another alternative I thought was to use path variables so that 'paramName' can be included in URL itself. So I tried like following:

'<appcontext>/<controller>/<action>/$paramName'

For validating the above URL I wrote specific mapping but some how it does not work too..

Following is the specific mapping I wrote:-

"/<controllerName>/<action>/$paramName" {
            controller:<controller to take request>
            action:<action to do task>
            constraints {
                paramName(nullable: false,empty:false, blank: false)
            }
        }

I tried to use spring annotation like @PathVariable and @RequestParam in controller as given below:-

 def action(@PathVariable("paramName") String param){
        //code goes here
    }

Answer

Jeff Scott Brown picture Jeff Scott Brown · Jul 2, 2014

If you name the method argument the same as the request parameter rename, Grails will take care of it for you...

// In UrlMappings.groovy
"/foo/$someVariable/$someOtherVariable" {
    controller = 'demo'
    action = 'magic'
}

Then in your controller:

// grails-app/controllers/com/demo/DemoController.groovy
class DemoController {
    def magic(String someOtherVariable, String someVariable) {
        // a request to /foo/jeff/brown will result in
        // this action being invoked, someOtherVariable will be
        // "brown" and someVariable will be "jeff"
    }
}

I hope that helps.

EDIT:

Another option...

If for some reason you want different names for the method arguments you can explicitly map a method argument to a request parameter like this...

import grails.web.RequestParameter
class DemoController {
    def magic(@RequestParameter('someVariable') String s1, 
              @RequestParameter('someOtherVariable') String s2) {
        // a request to /foo/jeff/brown will result in
        // this action being invoked, s2 will be
        // "brown" and s1 will be "jeff"
    }
}