(Quick Reference)

1.1 What's new in Grails 2.3? - Reference Documentation

Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari

Version: 2.3.8

1.1 What's new in Grails 2.3?

Improved Dependency Management

The default dependency resolution engine used by Grails has been changed to Aether, the dependency resolution engine used by Maven. Which engine you use can be configured in BuildConfig:

grails.project.dependency.resolver = "maven" // or ivy

Using Aether dependency resolution in Grails results in the same behavior as when using the Maven build tool, meaning improved snapshot handling, understanding of custom packaging types and so on.

In addition, the dependency-report command has been updated to print the dependency graph of the console, which helps in diagnosing dependency resolution failures. See the chapter on Dependency Resolution for more information.

Data Binder

Grails 2.3 includes a new data binding mechanism which is more flexible and easier to maintain than the data binder used in previous versions. The new data binder includes numerous enhancements including:

See the Data Binding section for details.

The legacy data binder may be used by assigning true to the grails.databinding.useSpringBinder property in grails-app/conf/Config.groovy. Note that the legacy binder does not support any of the new features provided by the new data binder.

Binding Request Body To Command Objects

If a request is made to a controller action which accepts a command object and the request includes a body, the body will be parsed and used to do data binding to the command object. This simplifies use cases where a request includes a JSON or XML body (for example) that can be bound to a command object. See the Command Objects documentation for more details.

Domain Classes As Command Objects

When a domain class is used as a command object and there is an id request parameter, the framework will retrieve the instance of the domain class from the database using the id request parameter. See the Command Objects documentation for more details.

Forked Execution

All major commands can now be forked into a separate JVM, thus isolating the build path from the runtime / test paths. Forked execution can be controlled via the BuildConfig:

grails.project.fork = [
   test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true], // configure settings for the test-app JVM
   run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], // configure settings for the run-app JVM
   war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256], // configure settings for the run-war JVM
   console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256]// configure settings for the Console UI JVM
]

See the documentation on Forked Mode for more information.

Test Runner Daemon

To speed up testing when using forked execution a new daemon will start-up in the background to run tests when using interactive mode. You can restart the daemon with the restart-daemon command from interactive mode:

$ grails> restart-daemon

Server-Side REST Improvements

Grails' REST support has been significantly improved with the addition of the following features:

  • Rich REST URL Mapping support with supports for resource mappings, singular resource mappings, nested resources, versioning and more
  • New extensible response rendering and binding APIs
  • Support for HAL, Atom and Hypermedia (HATEAOS)
  • Scaffolding for REST controllers

See the user guide for more information.

New Scaffolding 2.0 Plugin

Grails' Scaffolding feature has been split into a separate plugin. Version 2.0 of the plugin includes support for generating REST controllers, Async controllers, and Spock unit tests.

URL Mappings May Specify A Redirect

URL Mappings may now specify that a redirect should be triggered when the mapping matches an incoming request:

class UrlMappings {
    static mappings = {
        "/viewBooks"(redirect: '/books/list')
        "/viewAuthors"(redirect: [controller: 'author', action: 'list'])
        "/viewPublishers"(redirect: [controller: 'publisher', action: 'list', permanent: true])

// … } }

See the user guide for more information.

Async support

Grails 2.3 features new Asynchronous Programming APIs that allow for asynchronous processing of requests and integrate seamlessly with GORM. Example:

import static grails.async.Promises.*
…
def index() {
   tasks books: Book.async.list(),
         totalBooks: Book.async.count(),
         otherValue: {
           // do hard work
         }
}

See the documentation for further information.

Encoding / Escaping Improvements

Grails 2.3 features dedicated support for Cross Site Scripting (XSS) prevention, including :

  • Defaulting to HTML escaping all GSP expressions and scriptlets
  • Context sensitive encoding switching for tags
  • Double encoding prevention
  • Optional automatic encoding of all data in a GSP page not considered safe

See the documentation on Cross Site Scripting (XSS) prevention for more information.

Hibernate 3 and 4 support

The GORM for Hibernate 3 support for Grails has been extracted into a separate project, allowing new support for Hibernate 4 as a separate plugin.

Controller Exception Handling

Controllers may define exception handler methods which will automatically be invoked any time an action in that controller throws an exception.

// grails-app/controllers/demo/DemoController.groovy
package demo

class DemoController {

def someAction() { // do some work }

def handleSQLException(SQLException e) { render 'A SQLException Was Handled' }

def handleBatchUpdateException(BatchUpdateException e) { redirect controller: 'logging', action: 'batchProblem' }

def handleNumberFormatException(NumberFormatException nfe) { [problemDescription: 'A Number Was Invalid'] } }

See the controller exception handling docs for more information.

Namespaced Controllers

Controllers may now be defined in a namespace which allows for multiple controllers to be defined with the same name in different packages.

// grails-app/controllers/com/app/reporting/AdminController.groovy
package com.app.reporting

class AdminController {

static namespace = 'reports'

// … }

// grails-app/controllers/com/app/security/AdminController.groovy
package com.app.security

class AdminController {

static namespace = 'users'

// … }

// grails-app/conf/UrlMappings.groovy
class UrlMappings {

static mappings = { '/userAdmin' { controller = 'admin' namespace = 'users' }

'/reportAdmin' { controller = 'admin' namespace = 'reports' }

"/$namespace/$controller/$action?"() } }

<g:link controller="admin" namespace="reports">Click For Report Admin</g:link>
<g:link controller="admin" namespace="users">Click For User Admin</g:link>

See the namespaced controllers docs for more information.

Command Line

The create-app command will now by default generate the command line grailsw wrapper for newly created applications. The --skip-wrapper switch may be used to prevent the wrapper from being generated.

grails create-app appname --skip-wrapper