8.1.2 Controllers and Scopes

Available Scopes

Scopes are hash-like objects where you can store variables. The following scopes are available to controllers:

  • servletContext - Also known as application scope, this scope lets you share state across the entire web application. The servletContext is an instance of ServletContext

  • session - The session allows associating state with a given user and typically uses cookies to associate a session with a client. The session object is an instance of HttpSession

  • request - The request object allows the storage of objects for the current request only. The request object is an instance of HttpServletRequest

  • params - Mutable map of incoming request query string or POST parameters

  • flash - See below

Accessing Scopes

Scopes can be accessed using the variable names above in combination with Groovy’s array index operator, even on classes provided by the Servlet API such as the HttpServletRequest:

  1. class BookController {
  2. def find() {
  3. def findBy = params["findBy"]
  4. def appContext = request["foo"]
  5. def loggedUser = session["logged_user"]
  6. }
  7. }

You can also access values within scopes using the de-reference operator, making the syntax even more clear:

  1. class BookController {
  2. def find() {
  3. def findBy = params.findBy
  4. def appContext = request.foo
  5. def loggedUser = session.logged_user
  6. }
  7. }

This is one of the ways that Grails unifies access to the different scopes.

Using Flash Scope

Grails supports the concept of flash scope as a temporary store to make attributes available for this request and the next request only. Afterwards the attributes are cleared. This is useful for setting a message directly before redirecting, for example:

  1. def delete() {
  2. def b = Book.get(params.id)
  3. if (!b) {
  4. flash.message = "User not found for id ${params.id}"
  5. redirect(action:list)
  6. }
  7. ... // remaining code
  8. }

When the delete action is requested, the message value will be in scope and can be used to display an information message. It will be removed from the flash scope after this second request.

Note that the attribute name can be anything you want, and the values are often strings used to display messages, but can be any object type.

Scoped Controllers

Newly created applications have the grails.controllers.defaultScope property set to a value of "singleton" in application.yml. You may change this value to anyof the supported scopes listed below. If the property is not assigned a value at all, controllers will default to "prototype" scope.

Supported controller scopes are:

  • prototype (default) - A new controller will be created for each request (recommended for actions as Closure properties)

  • session - One controller is created for the scope of a user session

  • singleton - Only one instance of the controller ever exists (recommended for actions as methods)

To enable one of the scopes, add a static scope property to your class with one of the valid scope values listed above, for example

  1. static scope = "singleton"

You can define the default strategy in application.yml with the grails.controllers.defaultScope key, for example:

  1. grails:
  2. controllers:
  3. defaultScope: singleton
Use scoped controllers wisely. For instance, we don’t recommend having any properties in a singleton-scoped controller since they will be shared for all requests.