8.1.4 Redirects and Chaining

Redirects

Actions can be redirected using the redirect controller method:

  1. class OverviewController {
  2. def login() {}
  3. def find() {
  4. if (!session.user)
  5. redirect(action: 'login')
  6. return
  7. }
  8. ...
  9. }
  10. }

Internally the redirect method uses the HttpServletResponse object’s sendRedirect method.

The redirect method expects one of:

  • The name of an action (and controller name if the redirect isn’t to an action in the current controller):
  1. // Also redirects to the index action in the home controller
  2. redirect(controller: 'home', action: 'index')
  • A URI for a resource relative the application context path:
  1. // Redirect to an explicit URI
  2. redirect(uri: "/login.html")
  • Or a full URL:
  1. // Redirect to a URL
  2. redirect(url: "http://grails.org")
  1. // Redirect to the domain instance
  2. Book book = ... // obtain a domain instance
  3. redirect book

In the above example Grails will construct a link using the domain class id (if present).

Parameters can optionally be passed from one action to the next using the params argument of the method:

  1. redirect(action: 'myaction', params: [myparam: "myvalue"])

These parameters are made available through the params dynamic property that accesses request parameters. If a parameter is specified with the same name as a request parameter, the request parameter is overridden and the controller parameter is used.

Since the params object is a Map, you can use it to pass the current request parameters from one action to the next:

  1. redirect(action: "next", params: params)

Finally, you can also include a fragment in the target URI:

  1. redirect(controller: "test", action: "show", fragment: "profile")

which will (depending on the URL mappings) redirect to something like "/myapp/test/show#profile".

Chaining

Actions can also be chained. Chaining allows the model to be retained from one action to the next. For example calling the first action in this action:

  1. class ExampleChainController {
  2. def first() {
  3. chain(action: second, model: [one: 1])
  4. }
  5. def second () {
  6. chain(action: third, model: [two: 2])
  7. }
  8. def third() {
  9. [three: 3])
  10. }
  11. }

results in the model:

  1. [one: 1, two: 2, three: 3]

The model can be accessed in subsequent controller actions in the chain using the chainModel map. This dynamic property only exists in actions following the call to the chain method:

  1. class ChainController {
  2. def nextInChain() {
  3. def model = chainModel.myModel
  4. ...
  5. }
  6. }

Like the redirect method you can also pass parameters to the chain method:

  1. chain(action: "action1", model: [one: 1], params: [myparam: "param1"])
The chain method uses the HTTP session and hence should only be used if your application is stateful.