Table of Contents

Controller

Grails controller mainly handle the HTTP request. It also automatically map a URL to its method. The controller class must located at /grails-app/controllers/ directory.

Creating a Controller

Grails Console: Type the following code with your own controller name, and a controller with your app package will be created.

create-controller YOUR_CONTROLLER_NAME

Intellij: Right click the controller directory in Project View, and select New→Grails Controller in the pop up menu. Input the controller name in the pop up dialog, and Intellij will do the rest.

URL Mapping

By default, the controller name will be path of the URL. Assume our controller named TestingController:

class TestingController {

    def index() {
        render "/testing/index"
    }
    def a() {
        render "/testing/a"
    }
    def b() {
        render "/testing/b"
    }
}

When we run the app, we will have 3 new URLs

They are related to the controller's name, and method's name by grails convention.

Flash, Params, Session, Request, Response

Like Spring Boot, we can access params, session, request, response,… in the controller. To use them in controller, simply type flash, request, response, session, params inside a method. You do not need to add them into your method header as parameters as spring boot does. You can use it inside your controller such as:

def methodB() {
    String path = request.getPathInfo()
    response.setStatus(200)
    session.setAttribute("ATTRIBUTE_KEY", "My Object")
    String token = params.get("token")
    flash.message = "OK"
    render "/testing/methodB"
}

Flash (FlashScope)

Flash, or more correctly FlashScope, is a map for temporarily storage for next request, and it will be cleaned up afterward. You can put value in flash by flash.YOUR_KEY = YOUR_VALUE, and then in the view, gsp for instant, read the value and render it. It can store any type of Object.

Params

Params, or more correctly GrailsParameterMap, is a mapping for any kind of input from HTTP GET or POST. Assume we have a HTTP GET request like http://127.0.0.1/testing/methodB?token=MY_TOKEN, we can get this input by calling String token = params.get(“token”) in our methodB method.

Session, Request, Response

They are just Java servlet session, request, and response.

Method Taking Command Object as Parameter

It is possible to map a HTML form input to a parameter of a method in a controller. Assume we have a TestController, and a method called methodA which table a parameter (command object) CommandObject.

CommandObject:

class CommandObject implements Validateable {
    Long start
    Long end
    static constraints = {
        start nullable: true
        end nullable: true
    }
    String toString() {
        return start != null ? start : "" + " to " + end != null ? end : ""
    }
}

TestController:

class TestController {
    def methodA(CommandObject commandObject){
        render(commandObject.start+" "+commandObject.end)
    }
}

The URL for this method would be http://127.0.0.1/test/methodA. In order to pass such command object to methodA, we can do a HTTP GET request by http://127.0.0.1:8080/test/methodA?commandObject.start=1&commandObject.end=10, or by a HTTP POST request with a from in GSP like:

<g:form action="doEdit" method="post" class="iasloading">
   <g:hiddenField name="commandObject.start" value="1"/>
   <g:hiddenField name="commandObject.end=" value="10"/>
   <g:submitButton name="Submit"/>
</g:form>

Note that the command object need to implements Validateable, and you need to add the constraints{…}.

In the controller by default, the command object will be created once the method is called even if nothing has passed in. Grails will create the command object with its default constructor. The command object you can .validate() the command object if needed. You can pass multiple command objects in to a method as soon as their names match to the one in the function prototype. It is even possible to pass MultipartFile attachment to a command object, but you need to make sure that HTTP form enctype is multipart/form-data:

   <g:form action="some_action" method="POST" enctype="multipart/form-data">

Passing Values, Objects to GSP View

When creating a controller, a directory with the same name as the controller will be created under /grails-app/views/. We can pass the values from controller to view by using the following code. The model is the key here. it is a map with the key as the name we access the object in the view, and the value as the object name in the controller.

respond([], view: "YOUR_VIEW_NAME", model: [object1NameInView: object1InController,
                                            object2: object2,
                                            object3: object3])