Grails controllers support the concept of command objects. A command object is similar to a form bean in something like Struts and they are useful in circumstances when you want to populate a subset of the properties needed to update a domain class. Or where there is no domain class required for the interaction, but you need features such as data binding and validation.

Declaring Command Objects

Command objects are typically declared in the same source file as a controller directly below the controller class definition. For example:

class UserController {
	…
}
class LoginCommand {
   String username
   String password
   static constraints = {
           username(blank:false, minSize:6)
           password(blank:false, minSize:6)
   }
}

As the previous example demonstrates you can supply constraints to command objects just as you can with domain classes.

Using Command Objects

To use command objects, controller actions may optionally specify any number of command object parameters. The parameter types must be supplied so that Grails knows what objects to create, populate and validate.

Before the controller action is executed Grails will automatically create an instance of the command object class, populate the properties of the command object with request parameters having corresponding names and the command object will be validated. For Example:

class LoginController {
  def login = { LoginCommand cmd ->
         if(cmd.hasErrors()) {
                redirect(action:'loginForm')
         }
         else {
            // do something else
        }
  }
}

Command Objects and Dependency Injection

Command objects can participate in dependency injection. This is useful if your command object has some custom validation logic which may need to interact with Grails services:

class LoginCommand {
    def loginService

String username String password

static constraints = { username(validator: { val, obj -> obj.loginService.canLogin(obj.username, obj.password) }) } }

In this example the command object interacts with a bean injected by name from the Spring ApplicationContext.