(Quick Reference)

8.1.4 Redirects and Chaining

Version: 3.3.3

8.1.4 Redirects and Chaining

Redirects

Actions can be redirected using the redirect controller method:

class OverviewController {

    def login() {}

    def find() {
        if (!session.user)
            redirect(action: 'login')
            return
        }
        ...
    }
}

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):

// Also redirects to the index action in the home controller
redirect(controller: 'home', action: 'index')
  • A URI for a resource relative the application context path:

// Redirect to an explicit URI
redirect(uri: "/login.html")
  • Or a full URL:

// Redirect to a URL
redirect(url: "http://grails.org")
// Redirect to the domain instance
Book book = ... // obtain a domain instance
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:

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:

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

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

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:

class ExampleChainController {

    def first() {
        chain(action: second, model: [one: 1])
    }

    def second () {
        chain(action: third, model: [two: 2])
    }

    def third() {
        [three: 3])
    }
}

results in the model:

[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:

class ChainController {

    def nextInChain() {
        def model = chainModel.myModel
        ...
    }
}

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

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.