Professional Documents
Culture Documents
Key: GRAILS
Name: Grails
Description:
Grails web application framework
Available Pages
• Troubleshooting
• Community
• Contribute
• Developer Blogs
• Mailing lists
• User Groups
• Who we are
• Developer Documentation
• Compile Time Injection
• Developer - Dynamic Method Injection
• Developer - Groovy Server Pages
• Developer - Hibernate Integration
• Developer - Spring MVC Integration
• General Architecture
• Runtime Configuration
• Developer Guidelines
• Documentation
• Quick Start
• Reference
• Artifact Reference
• Builders Reference
• Hibernate Criteria Builder
• Spring Bean Builder
• Command Line
• Dynamic Methods Reference
• Controller Dynamic Methods
• DomainClass Dynamic Methods
• OperatorNamesInDynamicMethods
• Tag Library Reference
• GSP Tag Reference
• GSP Tag - collect
• GSP Tag - def
grails clean
In case your Grails application has been screwed and comes up with mysterious error messages try
grails clean
• tbd
• tbd
• tbd
• tbd
In case you have a bi-directional dependency, you need to care about proper synchronization
of both sides, see XXX
Get Involved!
Grails has a growing following and if you want to get involved the developers are all nice people
(promise!) who are keen to have ideas, code and just about anything contributed. There are a number of
ways to get involved with the Grails community, you can:
• Take a look at the Mailing lists archives and post new questions/ideas to the commnity!
• Head over to the Grails Wiki an ever growing knowledge base of information about Grails. Actually,
you're already at the Wiki, just click the "Edit" button at the bottom of this page!
• Get involved in the User Groups, the place where people meet to talk about Groovy and Grails.
• Come and chat to us on IRC at irc.codehaus.org where most Grails developers can be found in the
#groovy room
• Write a Blog post about Grails, or even a Tutorial! Just talking about your experiences with Grails
can either help others get involved or provide constructive feedback to the Grails team.
• Follow what is happening with Grails now and in the future with the Grails Issue Tracker and on the
Roadmap. Or even better checkout the latest commits!
• Contribute your own Custom Tags that could eventually be included in Grails core!
• Post some ideas for new Grails features in the development Sandbox. This is the area we where
play around with ideas before they are promoted into JIRA issues.
• Add one of the Grails buttons on the left to your site or blog to help spread the word about Grails
• Contribute yourself by becoming part of the Grails Team !
How to Contribute
We're always on the lookout for people who can contribute to Grails so if you have new ideas, patches to
submit, code to contribute anything let us know via the Mailing lists or contact Graeme the Grails project
lead.
Developer Blogs
Many of the Grails developers are active bloggers, see below for a list of developers and their blogs:
• Graeme's Blog
• Guillaume's Blog
• Dierk's WebTest Blog and Groovy in Action Blog
• Steven Devijver's Blog
• Marc Palmer's Blog
• Jeff Brown's Blog
• Jason Rudolph's Blog
• Marcel Overdijk's Blog
Here are the mailing lists that have been established for this project. For each list, there is a subscribe,
unsubscribe, and an archive link. If you have trouble subscribing via email you can go to
http://xircles.codehaus.org/manage_email and register an e-mail to subscribe.
NOTE: If you are using gmail to subscribe and you are using an alternate "send mail as" address, it will
not work. Use your actual gmail address to subscribe, and make sure you send messages from your
gmail account when you send messages to the list.
Once you've done that you can then choose which mailing lists you want to subscribe to on the Grails
project page:
http://xircles.codehaus.org/projects/grails
Grails was started by a small group of keen followers of the Groovy language and inspired by the "code
by convention" paradigm of frameworks like Ruby on Rails.
The project was initiated by Guillaume LaForge and founded by Steven Devijver and Graeme Rocher
(graemerocher@yahoo.co.uk) - who is the current Project Lead. Below the current active members on the
project and their roles:
Developer Documentation
These pages are designed to help new committers on the Grails project get up to speed on the various
parts of Grails and how they function:
General Architecture
Runtime Configuration
Artefact API
Dynamic Method Injection
Compile Time Injection
Spring MVC Integration
Hibernate Integration
SiteMesh Integration
Groovy Server Pages
Tag Libraries
Scaffolding Architecture
Command Line
Grails contains an architecture to implement compile time injection of properties, methods etc. This is
built on functionality provided by the GroovyClassLoader and is important when used in conjunction with
Java libraries because they are not aware of the Groovy runtime environment and hence dynamic
property injection does not work.
The core classes for compile time injection are found in the org.codehaus.groovy.grails.injection package.
As of this writing only injection of properties into domain classes is supported (sorry if this is out-of-date
when you read it). To do this create a class that implements the
org.codehaus.groovy.grails.injection.GrailsDomainClassInjector and add it as a bean definition to the
applicationContext.xml file.
import org.codehaus.groovy.grails.injection.*;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.control.SourceUnit;
If you want to add methods, this process can become tricky. The groovy AST (Abstract Syntax Tree)
MethodNode is a dom-like tree of command blocks, return blocks, etc. and can be tiresome to construct
(unless someone has created an editor, if so please say!). I got round this by using the SourceUnit to
parse and compile a String of groovy code into the MethodNode for me.
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.classgen.GeneratorContext;
The core classes that make up the Grails dynamic method injection architecture are found in the
org.codhaus.groovy.grails.commons.metaclass package. The
org.codhaus.groovy.grails.commons.metaclass.ProxyMetaClass class extends the Groovy MetaClass to
allow constructor, method and property interceptors to be set on the MetaClass which "intercept" calls.
A Groovy MetaClass is what Groovy uses to dispatch method, constructor and property calls to objects
with. These could be real methods or dynamically injected methods. Grails' ProxyMetaClass allows you to
intercept calls to methods that may be real or not and choose whether to invoke the target "real" method
at runtime. ProxyMetaClass tends to be used with instances and the setMetaClass method of
GroovyObject as opposed to being registered within the MetaClassRegistry:
Once you have a ProxyMetaClass instance registered as the objects MetaClass you can then set an
interceptor on the ProxyMetaClass to handle the interception. There are three interfaces for this:
Fortunately, Grails provides an abstract implementation of these that makes life easier called
AbstractDynamicMethodsInterceptor. This abstract class implements the DynamicMethods interface that
allows you to add dynamic methods, contructors and properties as objects. For example the following
code will register an anonymous AbstractDynamicMethodsInterceptor as the interceptor:
You can then add dynamic methods, constructors and properties to the interceptor which implement
either the DynamicMethodInvocation, DynamicConstructor or DynamicProperty interfaces. Fortunately
there are abstract implementations of these all:
Once the above has been added to my previously defined "go" object invoking the method from groovy
will print "world!" to standard out:
This mechanism is uses in several places including for controller and tag lib in the classes:
• ControllerDynamicMethods
• TagLibDynamicMethods
To make this even easier Grails provides a class called GroovyDynamicMethodsInterceptor which takes a
GroovyObject in the constructor, registers a ProxyMetaClass on it and sets itself as the interceptor
allowing you to shorten the above code example to:
The proxy/interception mechanism is best used on instances of GroovyObject, but Grails provides another
MetaClass called DelegatingMetaClass which takes an instance of the DynamicMethods interface in its
constructor and delegates to it hence not requiring any interceptors to be set on it. Essentially it attempts
to call a dynamic method first and if it fails falls back to trying to invoke a real method. This MetaClass is
used by domain classes in conjunction with the DomainClassMethods class which is an instance of
DynamicMethods.
The GSP implementation in Grails was forked from the original GSP, but has been heavily refactored and
is now based around the TemplateEngine pattern found in the rest of Groovy. The core classes for GSP
can be found in the org.codehaus.groovy.grails.web.pages package.
There is a servlet that maps to *.gsp that handles all GSP request called GroovyPagesServlet. This class
uses the GroovyPagesTemplateEngine class to process a GSP request.
As mentioned the API for the GroovyPagesTemplateEngine is very similar to the other TemplateEngine's
in Groovy, making GSP into a re-usable component. General API usage is as follows:
groovy.text.Template t = engine.createTemplate(context,request,response);
if(t != null) {
groovy.lang.Writable w = t.make();
Writer out = ..// get writer from somewhere
w.writeTo(out);
}
The Parse, Reverse, Scan, Strip and Tokens classes in the org.codehaus.groovy.grails.web.pages are
used to convert a GSP into a Groovy class that extends the GroovyPage class which in turn extends
groovy.lang.Script.
Hibernate Integration
Configuration
Grails uses Hibernate for ORM, but implements it's own configuration strategy for Hibernate to use
convention to perform ORM mapping. The result is GORM. The core Hibernate integration classes can be
found within the org.codehaus.groovy.grails.orm.hibernate directory. Within this package resides a Spring
factory bean called ConfigurableLocalSessionFactoryBean that extends the Spring factory bean for
creating Hibernate session factories allowing a custom hibernate Configuration class to be set.
Grails then provides its own configuration class within the org.codehaus.groovy.grails.orm.hibernate.cfg
package called DefaultGrailsDomainConfiguration this class extends the Hibernate Configuration the
implication of which means it will still read in a regular hibernate.cfg.xml file if you want to use Hibernate
XML mapping instead.
Grails provides a second Configuration class called GrailsAnnotationConfiguration that extends the
Hibernate AnnotationConfiguration class to allow EJB3 annotation mapping in Grails.
Persistence Methods
The dynamic methods that magically appear on domain classes such as "save" and "delete" can be found
in the package org.codehaus.groovy.grails.orm.hibernate.metaclass . They use the architecture described
in the section on Dynamic Method Injection.
Grails uses Spring MVC as the underlying web application framework. Spring MVC might not be the
simplist framework to use but it is most definitely one of the most extensible making it perfect for Grails.
The Grails servlet extends Spring's DispatcherServlet to bootstrap the Grails environment, there is then a
single Spring MVC controller called org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController
that handles all Grails controller requests.
1. Parses the URI into its components (controller name, action name, id etc.)
2. Looks up a GrailsControllerClass instance for the URI
3. Creates a new Grails controller instance
4. Configures the controller instance's dynamic methods and properties
5. Retrieves a scaffolder if is scaffolding is enabled for the controller
6. Gets a reference to the closure action to execute for the URI
7. Increments flash scope moving it on to its next state
8. Gets the view name for the URI
9. Executes any before inteceptors registered
10. Executes the closure that is the controller action if the before interceptor didn't return false
11. Creates a Spring MVC ModelAndView instance from the view name and the model returned by the
closure action
12. Executes any after interceptors registered passing returned model
13. Returns the Spring MVC ModelAndView instance
General Architecture
The core Grails classes that make up the foundation of Grails can be found in the
org.codehaus.groovy.grails.commons package. The classes within this package deal with the conventions
and most implement the interface org.codehaus.groovy.grails.commons.GrailsClass which defines
methods for retrieving various representations of the class name based on the convention.
The DefaultGrailsApplication class defines two constructors one which takes an array of Spring resources.
The resources are a set of the set of .groovy files that resides within the grails-app directory and are
loaded by the Spring applicationContext.xml file found in the WEB-INF directory. The
DefaultGrailsApplication class also defines a constructor that takes an array of classes which is mainly
used in test cases for example:
The above code creates an GrailsApplication instance with a domain class called Test and a controller
called TestController. The domain class is encapsulated by an instance of
org.codehaus.groovy.grails.commons.GrailsDomainClass and the controller by an instance of
org.codehaus.groovy.grails.commons.GrailsControllerClass
There are a number of utility classes for working with the commons package. The class
org.codehaus.groovy.grails.commons.GrailsClassUtils provides methods for evaluating the conventions of
classes and retrieving different naming representations. Since 0.5 these convention evaluation methods
are removed and are available on GrailsApplication via the Developer - Artefact API.
Runtime Configuration
Grails automatically configures itself at runtime using the conventions within the classes and Spring. The
class that performs the runtime configuration is called
org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator which takes a GrailsApplication
and produces a bunch of bean references which can be used to create a Spring application context.
The GrailsRuntimeConfigurator class does many things including, but not limited to:
An example of its usage can be seen in the grails.util.GrailsUtil class which is used when running unit
tests and scaffolding. It essentially bootstraps the Grails environment using the
GrailsRuntimeConfigurator class and an applicationContext.xml on the classpath:
When a Grails web application is executed this configuration takes place in the
org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet class which is a class that extends Spring
MVC's DispatcherServlet to bootstrap the Grails environment
Overview
If you're looking for documentation about the Grails source code see the Developer Documentation, this
page serves as a guideline to the processes for committers working on Grails. As Grails takes on more
developers it is important that a process is followed so that that Grails maintains a high level of quality.
This section details that process.
Clearly not every great idea should be added directly to Grails, as a commiter you have a responsibility to
inform others of new ideas before touching the codebase. The following process should be followed as a
general rule:
• Send an email to the developer list with proposals of the change/new feature
• If the change is agreed (and ultimately the final decision is down to the Grails project lead Graeme)
add a new JIRA issue.
• When committing the changes refer to the JIRA issue number in the commit comments, e.g.
GRAILS-001
• Make sure you only do minor commits without approval
Testing is seen as crucial to the success of the project and Grails aims for maximum coverage. Before
even thinking of committing anything make sure you have implemented sufficient unit tests to cover the
code.
It doesn't matter how complicated your unit tests become (and they're often more complicated than the
code itself with Grails) they must exist and they must cover as much as possible.
Before committing to Grails make sure you run the entire test suite against Grails and only commit once
the test suite is passing.
Directly following your commit monitor the Continuous Integration build server and ensure the build
completes successfully. A broken build must be immediately corrected.
The continuous integration compiles and tests with JDK 1.4. Make sure not to use any Java 5 specifics.
At the moment not every aspect of Grails is covered by a unit test. This will be corrected over time, but
these guidelines are in place so the situation doesn't degrade as we are still in a position to be able to
ensure Grails has a solid foundation for the future.
Documentation
Quick Start
The following makes it simple to start a grails project. There's also a screencast that follows these steps
for creating a small app.
Once you have installed Grails you can use the built-in target for creating new projects:
grails create-app
The target will prompt you for the name of your project and create the project structure below:
%PROJECT_HOME%
+ grails-app
+ conf --->location of configuration artifacts like data sources
+ controllers --->location of controller artifacts
+ domain --->location of domain classes
+ i18n --->location of message bundles for i18n
+ services --->location of services
+ taglib --->location of tag libraries
+ util --->location of special utility classes (e.g., codecs, etc.)
+ views --->location of views
+ layouts ---> location of layouts
+ hibernate ---> optional hibernate config
+ lib
+ spring ---> optional spring config
+ src
+ groovy ---> optional; location for Groovy source files
(of types other than those in grails-app/*)
+ java ---> optional; location for Java source files
+ war
+ WEB-INF
The "create-app" target created several Grails data source artifacts for you in the "<..>/grails-app/conf"
directory, one for each of the standard environments: DevelopmentDataSource, TestDataSource, and
ProductionDataSource. All the examples that follow operate on the development environment. For more
information on environments see Configuration#environments.
By default, each data source is configured with an in-memory HSQLDB database (great for testing, but
probably not that useful for live deployment) so this step is optional:
class DevelopmentDataSource {
boolean pooling = true
Configuring the data source is a simple matter of changing the values for the desired database and driver
and placing the driver jar file in the <..>/lib directory
Make sure you are in the root directory of your project (for argument sake "my-project) by typing
cd my-project
grails create-domain-class
The target will prompt you for the name of your domain class. A domain class is a persistent artifact and
all properties are by default persisted to the database (Go the the section on GORM (Grails Object
Relational Mapping) for more info):
class Book {
String title
String author
}
At this point you may want to create some test data. An easy way to do this is to build and save the
domain objects in the "init" closure of the Grails application bootstrap class found in
"<..>/grails-app/conf/ApplicationBootStrap.groovy":
class ApplicationBootStrap {
(Note that you can build and save domain objects here the same as in controllers or other parts of Grails
applications; see Grails Object Relational Mapping (GORM) for more on domain objects.)
Create a controller
Controllers are central to Grails applications they handle web requests and URLs of the request map to a
controller class and a closure within the class.
Run the "grails generate-all" target and type in the name of the controller. In our example we type
"Book" which generates a controller called grails-app/controllers/BookController.groovy. Open up
class BookController {
def scaffold = Book
}
Alternatively, you could also have left the generated controller alone, instead of replacing it with the
default scaffolding. It might be worth learning from.
Start Grails
grails run-app
This will startup in instance of the Jetty servlet engine running on port 8080. In order to start in on a
different port like e.g. 9090 use grails -Dserver.port=9090 run-app. To access the list of books open
up a browser and type:
http://localhost:8080/my-project/book/list
Or, as the "list" closure is the default action for the BookController you can type:
http://localhost:8080/my-project/book
Reference Guide
1. Command Line
2. Dynamic Methods & Properties
3. Artifact Reference
4. Tag Library
5. Validation
6. Builders
These are special properties and closures used to configure Grails artifacts.
• ApplicationBootstrap
• Codecs
• Controllers
• DataSources
• Domains
• Jobs
• Services
ApplicationBootstrap
• destroy
• init
Usage:
• configuration
• domain class creation
Codecs
Since: 0.4
Properties: none.
Closures:
• encode
Usage:
Controllers
Closures:
• beforeInterceptor
• index
Usage:
• ..
DataSources
• configClass
• dbCreate
• dialect
• driverClassName
• logSql
• password
• pooling
• url
• username
Closures: none.
Usage:
• Configuration
Domains
• belongsTo
• constraints
• hasMany
• mappedBy
• optionals
• transients
• withTable
Closures: none.
Usage:
Jobs
• cronExpression
• group
• name
• startDelay
• timeout
Closures: none.
Usage:
• ...
Services
• available
• byName
• transactional
Closures: none.
Usage:
• ...
Grails Builders.
Introduction
Grails uses many Groovy builders to provide mini-DSL like constructs for an array of different things. This
page details the builders with in Grails and provides a reference to the syntax.
Description
A builder for creating criteria-based queries analogous to those found in the Hibernate Criteria API, the
nodes on this builder map the the static methods found in the Restrictions class of the Hibernate Criteria
API. Example Usage:
def c = Account.createCriteria()
def results = c {
like("holderFirstName", "Fred%")
and {
between("balance", 500, 1000)
eq("branch", "London")
}
maxResults(10)
order("holderLastName", "desc")
}
If a node within the builder tree doesn't match a particular criterion it will attempt to set a property on
the Criteria object itself. Thus allowing full access to all the properties in this class. The below example
calls "setMaxResults" and "setFirstResult" on the Criteria instance:
import org.hibernate.FetchMode as FM
....
def results = c.list {
maxResults(10)
firstResult(50)
fetchMode("aRelationship", FM.EAGER)
}
c { ... }
It defaults to the 'list' call, if this is not desired use the specific methods 'list','get' and 'scroll' which return
a list, a unique result and a scrollable result set respectively.
Querying Associations
Associations can be queried by having a node that matches the property name. For example say the
Account class had many Transaction objects:
class Account {
We can query this association by using the property name "transaction" as a builder node:
def c = Account.createCriteria()
def now = new Date()
def results = c.list {
transactions {
between('date',now-10, now)
}
}
The above code will find all the accounts that have performed transactions within the last 10 days.
You can also nest such association queries within logical blocks:
def c = Account.createCriteria()
def now = new Date()
def results = c.list {
or {
between('created',now-10,now)
transactions {
between('date',now-10, now)
}
}
}
Here we find all accounts that have either performed transactions in the last 10 days OR have been
recently created in the last 10 days.
Projections to be used to customise the results. To use projections you need to define a "projections"
node within the criteria builder tree. There are equivalent methods within the projections node to the
methods found in the Hibernate Projections class:
def c = Account.createCriteria()
You can use Hibernate's ScrollableResults feature by calling the scroll method:
A result iterator that allows moving around within the results by arbitrary increments. The Query /
ScrollableResults pattern is very similar to the JDBC PreparedStatement/ ResultSet pattern and the
semantics of methods of this interface are similar to the similarly named methods on ResultSet.
Node Reference
or Logical OR operator
or {
between("balance", 500,
1000)
eq("branch", "London")
Motivation
Spring is very powerful, but the XML based syntax is very verbose and violates DRY at multiple levels
even with the recent additions to Spring 2.0. This Bean builder in Grails aims to provide a simplified way
of wiring together dependencies that uses Spring at its core.
In addition, Spring's regular way of configuration (via XML) is essentially static and very difficult to
modify and configure at runtime other than programmatic XML creation which is both error prone and
verbose. Grails' BeanBuilder changes all that by making it possible to programmatically wire together
components at runtime thus allowing you to adapt the logic based on system properties or environment
variables.
This enables the code to adapt to its environment and avoids unnecessary duplication of code (having
different Spring configs for test, development and production environments)
Grails provides a grails.spring.BeanBuilder class that uses dynamic Groovy to construct bean
definitions. The basics are as follows:
import org.apache.commons.dbcp.BasicDataSource
import org.codehaus.groovy.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean;
import org.springframework.context.ApplicationContext;
bb.beans {
dataSource(BasicDataSource) {
driverClassName = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:mem:grailsDB"
username = "sa"
password = ""
}
sessionFactory(ConfigurableLocalSessionFactoryBean) {
dataSource = dataSource
hibernateProperties = [ "hibernate.hbm2ddl.auto":"create-drop",
"hibernate.show_sql":true ]
}
The above example shows how you would configure Hibernate with an appropriate data source with the
BeanBuilder class.
Basically what is happening here is the name of each method call (in this case "dataSource" and
Bean references are resolved automatically be using the name of the bean. This can be seen in the
example above with the way the sessionFactory bean resolves the dataSource reference.
Certain special properties related to bean management can also be set by the builder, as seen in the
following code:
The strings in square brackets are the names of the equivalent bean attributes in Spring's XML definition.
Constructor arguments can be defined using parameters to each method that reside between the class of
the bean and the last closure:
bb.beans {
exampleBean(MyExampleBean, "firstArgument", 2) {
someProperty = [1,2,3]
}
}
The first argument to the closure is a reference to the bean configuration instance, which you can use to
configure factory methods and invoke any method on the AbstractBeanDefinition class:
bb.beans {
exampleBean(MyExampleBean) { bean ->
bean.factoryMethod = "getInstance"
bean.singleton = false
someProperty = [1,2,3]
}
}
As an alternative you can also use the return value of the bean defining method to configure the bean:
bb.beans {
def example = exampleBean(MyExampleBean) {
someProperty = [1,2,3]
Spring defines the concept of factory beans and often a bean is created not from a class, but from one of
these factories. In this case the bean has no class and instead you must pass the name of the factory
bean to the bean:
bb.beans {
myFactory(ExampleFactoryBean) {
someProperty = [1,2,3]
}
myBean(myFactory) {
name = "blah"
}
}
Note in the example above instead of a class we pass a reference to the myFactory bean into the bean
defining method. Another common task is provide the name of the factory method to call on the factory
bean. This can be done using Groovy's named parameter syntax:
bb.beans {
myFactory(ExampleFactoryBean) {
someProperty = [1,2,3]
}
myBean(myFactory:"getInstance") {
name = "blah"
}
}
Here the getInstance method on the ExampleFactoryBean bean will be called in order to create the
myBean bean.
Sometimes you don't know the name of the bean to be created until runtime. In this case you can use a
GString to invoke a bean defining method dynamically:
In this case the beanName variable defined earlier is used when invoking a bean defining method.
Furthermore, because sometimes bean names are not known until runtime you may need to reference
Here the example property of AnotherBean is set using a runtime reference to the "exampleBean". The
"ref" method can also be used to refer to beans from a parent ApplicationContext that is provided in the
constructor of the BeanBuilder:
Here the second parameter "true" specifies that the reference will look for the bean in the parent context.
You can use anonymous inner beans by setting a property of the bean to a closure that takes an
argument that is the bean type:
bb.beans {
marge(Person.class) {
name = "marge"
husband = { Person p ->
name = "homer"
age = 45
props = [overweight:true, height:"1.8m"] }
children = [bart, lisa]
}
bart(Person) {
name = "Bart"
age = 11
}
lisa(Person) {
name = "Lisa"
age = 9
}
}
In the above example we set the "marge" bean's husband property to a closure that creates an inner
bean reference. Alternatively if you have a factory bean you can ommit the type and just use passed
bean definition instead to setup the factory:
bb.beans {
personFactory(PersonFactory.class)
marge(Person.class) {
name = "marge"
TODO
You can use the BeanBuilder class to load external Groovy scripts that define beans using the same path
matching syntax defined here. Example:
Here the BeanBuilder will load all Groovy files on the classpath ending with SpringBeans.groovy and parse
them into bean definitions. An example script can be seen below:
beans = {
dataSource(BasicDataSource) {
driverClassName = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:mem:grailsDB"
username = "sa"
password = ""
}
sessionFactory(ConfigurableLocalSessionFactoryBean) {
dataSource = dataSource
hibernateProperties = [ "hibernate.hbm2ddl.auto":"create-drop",
"hibernate.show_sql":true ]
}
Usage:
Target Description
name value
Grails uses special features of Groovy to provide dynamic methods and properties that are accessible
from your classes without you defining them or inheriting from a base class.
This is extremely convenient and contributes to having far less "code noise" in your applications.
The dynamic features available vary depending on the type of class you are calling from.
Controllers
Properties
• actionUri
• controllerUri
• actionName
• controllerName
• flash
• grailsApplication
• grailsAttributes
• log 0.3
• params
• session
• request
• response
• servletContext
Methods
• bindData
• chain
• render
• redirect
• getViewUri
• getTemplateUri
Domain Classes
Properties
Methods
• add
• add*
• delete
• discard
• hasErrors
• ident
• merge
• refresh
• save
• validate
Static Methods
• count
• countBy*
• createCriteria
• executeQuery
• executeUpdate
• exists
• find
• findAll
• findBy*
• findAllBy*
• findWhere
• findAllWhere
• get
• getAll
• list
• listOrderBy*
• withCriteria
• withTransaction
Properties
actionUri
Description
controllerUri
Description
actionName
Description
controllerName
Description
flash
Description
A map that allows temporary storage of objects for the next request and the next request only. The
subequent request will clear the storage of any variables stored in the first
request. This is a convenience map that allows you to store information temporarily, which is very
convenient when using redirection or chaining.
grailsApplication
Description
Example
grailsAttributes
Description
Example
log
Description
An instance of the Log4J logger for the controller. Grails creates a log per controller, which you can call
on at any time to perform logging. When configuring Log4J using WEB-INF/log4j.properties you should
use properties of the form:
log4j.logger.TestController=debug, stdout
Where "TestController" is the fully qualified class name of your controller class.
Example
params
Description
Example
request
Description
The HttpServletRequest instance for the request. Request attributes can be accessed with the Map syntax
provided by groovy
Example
request['anAttribute']
request.getHeader("user-agent")
response
Description
Example
response.setHeader("myheader", "myvalue")
servletContext
Description
session
Description
Example
Methods
bindData
Description
Binds data to a target instance performing type conversion if necessary. Useful for binding request
parameters to properties of objects. Since 0.4 this has been modified to never assign values for the
special ORM properties "id" or "version", nor the special Groovy properties (for Groovy classes)
'metaClass' and 'properties'. Note that this only operates on the top-level object currently, nested object
id/version etc assignments must be suppressed explicitly using the "excludes" parameter.
Parameters
Examples
chain
Description
Parameters
Examples
getViewUri
Description
Retrieves the relative uri of a named view within the Grails application. If the view contains a '/' at the
start it will be resolved relative to the views folder as a shared view otherwise it will be relative to the
current controller
Parameters
Examples
getTemplateUri
Description
Retrieves the relative uri of a named template within the Grails application. If the template contains a '/'
at the start it will be resolved relative to the views folder as a shared template otherwise it will be relative
to the current controller
Parameters
Examples
redirect
Description
Redirects the current action to another action, optionally passing parameters and/or errors
Parameters
Examples
redirect(uri:"book/list")
redirect(action:"show")
redirect(controller:"book",action:"list")
redirect(action:"show",id:4, params:[author:"Stephen King"])
render
Description
A multi-purpose method for rendering responses to the client which is best illustrated with a few
examples!
Parameters
Examples
Properties
errors
Description
A list of errors from the last call to the "validate" or "save" method
Example
constraints
Description
Example
properties
Description
Example
Methods
add
Description
Parameters
• to - specifies the hasMany relationship name to which the object is being added
Example
add*
Description
Adds a domain class relationship for one-to-many or many-to-many relationship, where the relationship
is indicated by the class used as the suffix to the method.
Example
delete
Description
Example
def b = Book.get(1)
b.delete()
discard
Description
Discards any changes that have been made during an update. Note that this method will not clean or
reset the object with the original values it will just prevent it from being automatically saved by Grails.
Example
def b = Book.get(1)
b.title = "Blah"
b.discard() // changes won't be applied now
hasErrors
Description
True if the domain class instance has errors following a call to "validate" or "save"
Example
Description
Returns the value of the identity property of the domain class regardless of the name of the identity
property itself
Example
println b.ident()
merge
Description
refresh
Description
Example
def b = Book.get(1)
b.refresh()
save
Description
Saves a domain class instance to the database cascading updates to any child instances if required.
Returns false if validation failed and the instance was not saved
Parameters
Example
validate
Description
Example
Static Methods
count
Description
Counts the number of instances in the database and returns the result
Parameters
None
Example
Description
Dynamic method that uses the properties of the domain class to allow the creation of Grails query
method expressions that count the number of records returned
Examples
class Book {
Long id
Long version
String title
Date releaseDate
String author
}
createCriteria
Description
Example
def c = Account.createCriteria()
def results = c {
like("holderFirstName", "Fred%")
and {
between("balance", 500, 1000)
eq("branch", "London")
}
maxResults(10)
order("holderLastName", "desc")
}
exists
Description
Parameters
Example
if(Account.exists(1)) {
// do something
}
executeQuery
Description
Parameters
Example
find
Description
Parameters
• query (required) - Either an HQL query or a instance of the domain class for query by example
• params (optional) - A List of parameters for a positional parametrized HQL query
• (Since 0.5) params also could be a Map of HQL named parameters
Example
findAll
Description
Finds all of the domain class instances for the specified query
Syntax
Book.findAll()
Book.findAll(example)
Book.findAll(query,params)
Book.findAll(query,params,pageMap)
Book.findAll(query,params,max)
Book.findAll(query,params,max,offset) // (since 0.5)
Parameters
• query (optional) - Either an HQL query or a instance of the domain class for query by example
• example (optional) - The instance of requested domain object for query by example
• params (optional) - A List of parameters for a positional parametrized HQL query
• (Since 0.5) params also could be a Map of HQL named parameters
• pageMap (optional) - The Map containing parameters 'max' or/and 'offset' (see examples below)
• max (optional) - The maximum number of results to retrieve
• (Since 0.5) offset (optional) - The offset from the first result to find from
Examples
findBy
Description
Dynamic method that uses the properties of the domain class to allow the creation of Grails query
method expressions that return the first result of the query
Examples
class Book {
Long id
Long version
String title
Date releaseDate
String author
}
findAllBy
Description
Examples
class Book {
Long id
Long version
String title
Date releaseDate
String author
}
findWhere
Description
Uses named arguments that match the property names of the domain class to produce a query that
returns the first result.
Examples
class Book {
Long id
Long version
String title
Date releaseDate
String author
}
findAllWhere
Description
Examples
class Book {
Long id
Long version
String title
Date releaseDate
String author
}
get
Description
Retrieves an instance of the domain class for the specified id, otherwise returns null
Examples
def b = Book.get(1)
getAll
Description
(Since 0.5) Retrieves an instances of the domain class for the specified ids and returns a list of these
instances, ordered by the original ids list. If some of provided ids are null or there are no instances with
these ids, then result list will contain null values on corresponding positions.
Examples
list
Parameters
Examples
// list everything
def results = Book.list()
// list 10 results
def results = Book.list(max:10)
// list 10 results, offset by 100
def results = Book.list(max:10, offset:100)
// list 10 results, offset by 100, orderd by title in descending order
def results = Book.list(max:10, offset:100, sort:"title", order:"desc")
listOrderBy
Description
Lists all of the instances of the domain class ordered by the property in the method expression
Parameters
Examples
withCriteria
Description
• arguments (optional) - A map on named arguments that will be set on the criteria instance
• closure - A closure that defines the criteria
Examples
withTransaction
Description
Parameters
• closure - A closure that gets passed an instance of the Spring TransactionStatus to allow
programmatic management of savepoints (See SavepointManager) and transaction rollback
Examples
Book.withTransaction { tx ->
def b = new Book(title:"Groovy in Action")
b.save()
The following operator names can be used within the respective dynamic methods names (countBy*,
findBy*, findAllBy*)
• LessThan
• LessThanEquals
• GreaterThan
• GreaterThanEquals
• Between
• Like
• Ilike (i.e. ignorecase like)
• IsNotNull
• IsNull
• Not
• Equal
• NotEqual
• And
• Or (can sometimes be problematic as of 0.5-snap)
The above operator names can be considered keywords, i.e. you will run into problems when querying
domain classes that have one of these names used as property names.
Grails supports both GSP and JSP as view technologies. There are however some key differences between
the 2 view technologies which are listed below:
There are many shared tags but some additional ones for both GSP (mainly groovy syntax tags) and JSP
hence we have 2 reference sections:
Logical Tags
• if
• else
• elseif
Iterative Tags
• while
• each
• collect
• findAll
• grep
Assignment Tags
• def
• set
Linking Tags
• link
• createLink
• createLinkTo
Ajax Tags
• remoteField
• remoteFunction
• remoteLink
• formRemote
• submitToRemote
Form Tags
• actionSubmit
• actionSubmitImage
• checkBox
• currencySelect
UI Tags
• richTextEditor
• render
• renderErrors
• layoutHead
• layoutBody
• layoutTitle
• pageProperty
• paginate
• sortableColumn (Since 0.5)
Validation Tags
• eachError
• hasErrors
• message
Tag - collect
Description
Uses the Groovy JDK collect method to iterate over each element of the specified object transforming the
result using the expression in the closure
Parameters
Examples
Books titles:
<g:collect in="${books}" expr="it.title">
<p>Title: ${it}</p>
</g:collect>
Tag - def
Description
Parameters
Examples
Tag - each
Description
Uses the Groovy JDK each method to iterate over each element of the specified object
Parameters
Note that var must be specified when the iterator value is to be used from within the body of a
GSP Dynamic Tag , such as in g:link. See the example below.
Examples
<g:each in="${books}">
<p>Title: ${it.title}</p>
<p>Author: ${it.author}</p>
</g:each>
Another example, where a named item is necessary (otherwise the access to the title property will fail):
<tbody>
<g:each status="i" in="${itemList}" var="item">
Tag - else
Description
Parameters
None
Examples
Tag - elseif
Description
Parameters
Examples
Tag - findAll
Description
Uses the Groovy JDK findAll method to iterate over each element of the specified object that match the
GPath expression within the attribute "expr"
Parameters
Examples
Tag - grep
Description
Uses the Groovy JDK grep method to iterate over each element of the specified object that match the
specified "filter" attribute. The filter can be different instances such as classes, regex patterns etc.
Parameters
Examples
Tag - if
Description
Parameters
Examples
Tag - layoutBody
Description
Used in layouts to output the contents of the body tag of the decorated page.
Parameters
None
Examples
<html>
<head>
<meta name="layout" content="myLayout" />
<script src="myscript.js" />
</head>
<body>Page to be decorated</body>
</html>
<html>
<head>
<script src="global.js" />
<g:layoutHead />
</head>
<body><g:layoutBody /></body>
</html>
Results in:
<html>
<head>
<script src="global.js" />
<script src="myscript.js" />
</head>
<body>Page to be decorated</body>
</html>
Tag - layoutHead
Description
Used in layouts to output the contents of the head tag of the decorated page. Equivalent to the SiteMesh
<decorator:head /> tag.
Parameters
None
Examples
<html>
<head>
<meta name="layout" content="myLayout" />
<script src="myscript.js" />
</head>
<body>Page to be decorated</body>
</html>
<html>
<head>
<script src="global.js" />
<g:layoutHead />
</head>
<body><g:layoutBody /></body>
</html>
Results in:
<html>
<head>
<script src="global.js" />
<script src="myscript.js" />
</head>
<body>Page to be decorated</body>
</html>
Tag - layoutTitle
Description
Used in layouts to output the contents of the title tag of the decorated page. Equivalent to the SiteMesh
<decorator:title /> tag.
Parameters
None
Examples
<html>
<head>
<meta name="layout" content="myLayout" />
<title>Hello World!</title>
<script src="myscript.js" />
</head>
<body>Page to be decorated</body>
</html>
<html>
<head>
<title><g:layoutTitle default="Some Title" /></title>
<script src="global.js" />
<g:layoutHead />
</head>
<body><g:layoutBody /></body>
</html>
Results in:
<html>
<head>
<title>Hello World!</title>
<script src="global.js" />
<script src="myscript.js" />
</head>
<body>Page to be decorated</body>
</html>
Tag - pageProperty
Description
Used in layouts to output the contents a property of the decorated page. Equivalent to the SiteMesh
<decorator:getProperty/> tag.
Parameters
None
Examples
<html>
<head>
<meta name="layout" content="myLayout" />
<script src="myscript.js" />
</head>
<body onload="alert('hello');">Page to be decorated</body>
</html>
<html>
<head>
<script src="global.js" />
<g:layoutHead />
</head>
<body onload="${pageProperty(name:'body.onload')}"><g:layoutBody /></body>
</html>
Results in:
<html>
<head>
<script src="global.js" />
<script src="myscript.js" />
</head>
<body onload="alert('hello');">Page to be decorated</body>
</html>
Tag - paginate
Description
Parameters
Examples
class Book {
String title
String author
}
Example controller:
class BookController {
def list = {
[books: Book.list(params)]
}
}
or
Tag - set
Description
Parameters
Examples
Description
Parameters
Attribute title or titleKey is required. When both attributes are specified then titleKey takes precedence,
resulting in the title caption to be resolved against the message source. In case when the message could
not be resolved, the title will be used as title caption.
Examples
Tag - while
Description
Parameters
Examples
Tag - actionSubmit
Description
Creates a submit button with the indicated value. Javascript event handlers can be added using the
same parameter names as in HTML.
Parameters
• value (required) - The title of the button and name of action when not explicitly defined.
• action [since 0.5] (optional) - The name of the action to be executed.
Examples
Tag - actionSubmitImage
Description
Creates a submit button using the input type="image" with the indicated value. Javascript event
handlers can be added using the same parameter names as in HTML.
Parameters
• value (required) - The title of the button and name of action when not explicitly defined.
• action [since 0.5] (optional) - The name of the action to be executed.
• src - The source of the image to use.
Note that you cannot use multiple actionSubmitImage tags on the same form and have it work in
MS IE without adding some custom JavaScript. MS IE6 and IE7 do not send the value attribute to
the server when submitting, so the "action" attribute on this tag is not useful to you unless
targetting non-IE users or adding custom Javascript.
Examples
Tag - checkBox
Description
Creates a checkbox form field. All the usual HTML elements apply beyond the below:
Parameters
Examples
// a checked checkbox
<g:checkBox name="myCheckbox" value="${true}" />
Tag - createLink
Description
Creates a link that can be used where necessary (for example in an href, javascript, ajax call etc.)
Parameters
• action (optional) - the name of the action to use in the link, if not specified the default action will
be linked
• controller (optional) - the name of the controller to use in the link, if not specified the current
controller will be linked
• id (optional) - The id to use in the link
• url (optional) - A map containing the action,controller,id etc.
Examples
class BookController {
def defaultAction="list"
def list = { [ books: Book.list( params ) ] }
def show = { [ book : Book.get( params['id'] ) ] }
}
Results in:
Tag - createLinkTo
Description
Creates a link that can be used where necessary (for example in an href, javascript, ajax call etc.)
Parameters
• dir (optional) - the name of the directory within the grails app to link to
• file (optional) - the name of the file within the grails app to link to
Examples
Results in:
Tag - currencySelect
Description
Helper tag for creating HTML selects for selecting from a list of currency symbols (eg. 'EUR', 'USD' etc.).
Parameters
• from (optional) - The currency symbols to select from, defaults to the major ones if not specified
• value (optional) - The currency value as the currency code. Defaults to the currency for the current
Locale if not specified
Examples
Tag - datePicker
Description
Creates a date picker which renders as selects for the day,month,year,hour and second of the day.
Parameters
Examples
Example usages:
Tag - eachError
Description
Loops through each error of the specified bean or model. If no arguments are specified it will go through
all model attributes and check for errors.
Parameters
Examples
<g:eachError bean="${book}">
<li>${it}</li>
</g:eachError>
Loop through each error in the title field of the "book" bean:
Tag - form
Description
Creates a form that submits to a controller, action, and/or id. Beyond what is below all the usual HTML
attributes apply.
Parameters
• action (optional) - the name of the action to use in the link, if not specified the default action will
be linked
• controller (optional) - the name of the controller to use in the link, if not specified the current
controller will be linked
• id (optional) - The id to use in the link
• url (optional) - A map containing the action,controller,id etc.
Examples
class Book {
def list = { [ books: Book.list( params ) ] }
def show = { [ book : Book.get( params['id'] ) ] }
}
Tag - formRemote
Description
Creates a form tag that uses a remote uri to execute an ajax call serializing the form elements falling
back to a normal form submit if javascript is not supported.
Parameters
• url - The url to submit to, either a map contraining keys for the action,controller and id or string
value
• action (optional) - The action to execute as a fallback, defaults to the url if non specified
• update (optional) - Either a map containing the elements to update for 'success' or 'failure' states,
or a string with the element to update in which cause failure events would be ignored
• before (optional) - The javascript function to call before the remote function call
• after (optional) - The javascript function to call after the remote function call
• asynchronous (optional) - Whether to do the call asynchronously or not (defaults to true)
• method (optional) - The method to use the execute the call (defaults to "post")
Events
Examples
class Book {
def defaultAction="list"
def list = { [ books: Book.list( params ) ] }
def show = { [ book : Book.get( params['id'] ) ] }
}
Tag - hasErrors
Description
Checks whether a bean, request scope, or model reference has any errors and if it does invokes the body
of the tag. Typically used in conjunction with either <g:eachError> or <g:renderErrors>
Parameters
Examples
Checks whether there are any errors for any bean throughout the request scope:
<g:hasErrors>
<g:eachError><p>${it.defaultMessage}</p></g:eachError>
</g:hasErrors>
Checks whether there are any errors for the specified bean
<g:hasErrors bean="${book}">
<g:eachError><p>${it.defaultMessage}</p></g:eachError>
</g:hasErrors>
Checks whether there are any errors for the field "title" of the specified "book" bean:
As a method call in GSP only. In this case we check for a field error on a particular field and set a CSS
class on the surround div thus allowing us to highlight the error with a red border for example:
Tag - hiddenField
Description
Creates a input of type 'hidden' (a hidden field). All the usual HTML elements apply beyond the below:
Parameters
Examples
Tag - link
Description
Creates a html anchor tag with the href set to based on the parameters specified
Parameters
• action (optional) - the name of the action to use in the link, if not specified the default action will
be linked
• controller (optional) - the name of the controller to use in the link, if not specified the current
controller will be linked
• id (optional) - The id to use in the link
• params (optional) - A map containing request parameters
• url (optional) - A map containing the action,controller,id etc.
Examples
class BookController {
def defaultAction="list"
def list = { [ books: Book.list( params ) ] }
def show = { [ book : Book.get( params['id'] ) ] }
}
Note that id takes a ${foo} parameter but ${foo} expansions will NOT work in the params
attribute.
Results in:
An "it" variable in the body of a nested tag (i.e. if you have a g:link nested in a g:each) generally
runs into compilation problems. This can be easily resolved by naming your parameter in the
g:each by passing a var parameter.
Tag - localeSelect
Description
Parameters
• value (optional) - The set locale, defaults to the current request locale if not specified
Examples
Tag - message
Description
Resolves a message from the given code or error. Normally used in conjunction with "eachError". One of
either the "error" attribute or the "code" attribute is required. Messages are resolved from the
"grails-app/i18n/messages.properties" bundle.
Parameters
• error (optional) - The error to resolve the message for. Used for built-in Grails messages.
• code (optional) - The code to resolve the message for. Used for custom application messages.
• default (optional) - The default message to output if the error or code cannot be found in
messages.properties.
• args (optional) - A list of argument values to apply to the message, when code is used.
Examples
<g:eachError bean="${book}">
<li><g:message error="${it}" /></li>
</g:eachError>
Note that this is typically used for built-in Grails messages, rather than user application messages. For
user application messages, use the code parameter, as illustrated below.
For a more complex example, to output your own message with parameters and a default message, you
might use the following code from your controller:
flash.message = "book.delete.message"
flash.args = [ "stupidbook" ]
flash.defaultMsg = "book deleted"
In the above, don't try to rename flash.defaultMsg as "flash.default". You'll get parser errors because
default is a reserved word (Note that on the other hand, you can specify it as flash['default'] because
then you are using it as a string key). You would then specify the following in messages.properties:
which would result in the output "Book stupidbook deleted." If you had misnamed the message or not
specified it in messages.properties, your default message of "book deleted" would be output.
Tag - remoteField
Description
Creates a text field that sends its value to a remote link when it changes. By default the parameter name
sent is called 'value', this can be changed by specifying a 'paramName' attribute.
Parameters
Events
Examples
Tag - remoteFunction
Description
Creates a remote javascript function that can be assigned to a DOM event to call the remote method
Parameters
• action (optional) - the name of the action to use in the link, if not specified the default action will
be linked
• controller (optional) - the name of the controller to use in the link, if not specified the current
controller will be linked
• id (optional) - The id to use in the link
• update (optional) - Either a map containing the elements to update for 'success' or 'failure' states,
or a string with the element to update in which cause failure events would be ignored
• before (optional) - The javascript function to call before the remote function call
• after (optional) - The javascript function to call after the remote function call
• asynchronous (optional) - Whether to do the call asynchronously or not (defaults to true)
• method (optional) - The method to use the execute the call (defaults to "post")
• params (optional) - Parameters to send to the controller
Events
Examples
class Book {
def defaultAction="list"
def list = { [ books: Book.list( params ) ] }
def show = { [ book : Book.get( params['id'] ) ] }
<select onchange="${remoteFunction(action:'bookbyname',update:[success:'great',
failure:'ohno'], params:'\'bookName=\' + this.value' )}">
<option>first</option>
<option>second</option>
</select>
Notes:
Tag - remoteLink
Description
Parameters
• action (optional) - the name of the action to use in the link, if not specified the default action will
be linked
• controller (optional) - the name of the controller to use in the link, if not specified the current
controller will be linked
• id (optional) - The id to use in the link
• params(optional) - Request parameter map
• update (optional) - Either a map containing the elements to update for 'success' or 'failure' states,
or a string with the element to update in which cause failure events would be ignored
• before (optional) - The javascript function to call before the remote function call
• after (optional) - The javascript function to call after the remote function call
• asynchronous (optional) - Whether to do the call asynchronously or not (defaults to true)
• method (optional) - The method to use the execute the call (defaults to "post")
Events
Examples
class Book {
def defaultAction="list"
def list = { [ books: Book.list( params ) ] }
def show = { [ book : Book.get( params['id'] ) ] }
Example usages for above controller (note that the params example is for use with the Dojo AJAX
implementation):
Tag - render
Description
Applys an inbuilt or user defined Groovy template against a model so that templates can be re-used for
lists or instance or a single instance
Parameters
Examples
class Book {
String title
String author
}
Example template:
This template can now be re-used whether you have a list of books or a single book. For a list the
template will be repeated for each instance:
or
or you could create a template that handles a certain type of model. For example the template below:
Could be used with the model as below. The disadvantage of this technique however is that the template
is less re-usable
Note that if the value of the template attribute starts with a '/' it will be resolved relative to the views
folder. This is useful for sharing templates between views. Without the leading '/' it will be first be
resolved relative to the current controller's view folder then, failing that, the top level views folder. In
either case the template file must be named with a leading underscore ('_') but referenced in the
template attribute without that underscore or the '.gsp' suffix.
Tag - renderBean
Description
The displayBean tag displays a bean in the scope with different possible views:
• a default display view of an instance of a domain class (with a simple table with labels right-aligned,
and associated values in the left column)
• a form view with a table like above, pre-filled if the bean is in the current scope, or void for a
creation, with the right widgets for each type of bean property (checkbox, date picker, text area,
etc...)
• a third optional but interesting view could be a mix of the two above with something like
edit-in-place table which would replace the values with input widgets when clicking on the value
label
Parameters
• view - the type of the view, being one of "table", "form", "edit-in-place"
• form - the name of the form containing the values of the properties of the bean (not needed in the
"table" view)
• bean - the name of the bean in the scope to display
• domain-class - the class name of the bean to display
Example
Tag - renderErrors
Description
Allows rendering of errors in different formats (at the moment only an HTML list is implemented but
others (including JSON) to come soon)
Parameters
• as (optional) - What to render it as current options are "list". Defaults to "list" if not specified.
• bean (optional) - The name of the bean to check for errors
• model (optional) - The name of model, an map instance, to check for errors
• field (optional) - The field within the bean or model to check for errors for
Examples
Tag - richTextEditor
Description
A Rich Text Editor component that by default uses fckeditor with a basepath of /fckeditor.
Parameters
Examples
Tag - select
Description
Parameters
Examples
// create select with internationalized labels (this is useful for small static lists and the
inList constraint)
// expected properties in messages.properties:
// book.category.M=Mystery
// book.category.T=Thriller
// book.category.F=Fantasy
<g:select name="book.category" from="${['M', 'T', 'F']}" valueMessagePrefix="book.category" />
${select(from:aList,value:aValue)}
Tag - submitToRemote
Description
Creates a button that submits the surrounding form as a remote ajax call serializing the fields into
parameters.
Parameters
• url - The url to submit to, either a map contraining keys for the action,controller and id or string
value
• action (optional) - The action to execute as a fallback, defaults to the url if non specified
• update (optional) - Either a map containing the elements to update for 'success' or 'failure' states,
or a string with the element to update in which cause failure events would be ignored
• before (optional) - The javascript function to call before the remote function call
• after (optional) - The javascript function to call after the remote function call
• asynchronous (optional) - Whether to do the call asynchronously or not (defaults to true)
• method (optional) - The method to use the execute the call (defaults to "post")
Events
Examples
class Book {
def list = { [ books: Book.list( params ) ] }
def show = { [ book : Book.get( params['id'] ) ] }
}
Tag - textArea
Description
Creates a HTML text area element. An implicit "id" attribute is given the same value as name unless you
explicitly specify one. All the usual HTML elements apply beyond the below:
Parameters
Examples
Tag - textField
Description
Creates a input of type 'text' (a text field). An implicit "id" attribute is given the same value as name
unless you explicitly specify one. All the usual HTML elements apply beyond the below:
Parameters
Examples
Tag - timeZoneSelect
Description
Helper tag for creating HTML selects for selecting from a list of time zones
Parameters
• value (optional) - An instance of java.util.TimeZone. Defaults to the time zone for the current
Locale if not specified
Examples
Tag - validate
Description
Parameters
Examples
class User {
String login
String pwd
def constraints = {
login(length:5..15,unique:true)
pwd(length:5..15)
}
}
The below used submits to a "login" action. The field names match those within the class defined about:
This allows us to apply the validate tag against the constraints set in the domain class and produce the
necessary
javascript to perform client side validation. Tag usage:
Linking Tags
• link
• createLink
Ajax Tags
• remoteFunction
• remoteLink
• formRemote
• submitToRemote
Form Tags
• form
• checkBox
• datePicker
• select
• currencySelect
• localeSelect
• timeZoneSelect
UI Tags
(Coming Soon)
Rendering Tags
• render
• renderErrors
Validation Tags
• eachError
• hasErrors
• message
• Example
• Reference
° blank
° creditCard
° email
° inList
° length
° matches
° max
° maxLength
° maxSize
° min
° minLength
° minSize
° notEqual
° nullable
° range
° scale
° size
° unique
° url
° validator
Example
class User {
Long id
Long version
String login
String password
static constraints = {
login(length:5..15,blank:false,unique:true)
password(length:5..15,blank:false)
}
}
login(blank:false)
creditCard
cardNumber(creditCard:true)
contactEmail(email:true)
inList
Usage: constrains a value so that it must be contained within the given list
Example:
length
login(length:5..15)
matches
login(matches:"[a-zA-Z]")
max
Usage: sets the maximum value of a class that implements java.lang.Comparable. The same type needs
to be used as the property itself.
Example:
age(max:new Date())
price(max:999F)
maxLength
login(maxLength:5)
maxSize
Example:
children(maxSize:25)
Usage: sets the minimum value of a class that implements java.lang.Comparable. The same type needs
to be used as the property itself.
Example:
age(min:new Date())
price(mix:0F)
minLength
login(minLength:5)
minSize
Example:
children(minSize:5)
notEqual
login(notEqual:"Bob")
nullable
age(nullable:false)
range
Usage: Uses a Groovy range to ensure that a property's value occurs within a specified range
Example:
age(range:minAge..maxAge)
scale
Since: 0.4
Usage: Set to the desired scale for floating point numbers (i.e., the number of digits to the right of the
decimal point). This constraint is applicable for properties of the following types: java.lang.Float,
java.lang.Double, and java.math.BigDecimal (and its subclasses). When validation is invoked, this
constraint determines if the number includes more nonzero decimal places than the scale permits. If so,
it automatically rounds the number to the maximum number of decimal places allowed by the scale. This
constraint does not generate validation error messages.
Example:
salary(scale:2)
size
Example:
children(size:5..15)
unique
login(unique:true)
[Since 0.5] Scope of unique constraint can be specified. "Scope" - is a name of another property of the
same class, or list of such names. Semantic in these cases is: pair of constrained property value and
scope property value must be unique (or combination of constrained property value and all scope
property values must be unique).
Example:
group(unique:'department')
In the above example group name must be unique in one department but there might be groups with
same name in different departments.
Another example:
login(unique:['group','department'])
In this example login must be unique in group and department. There might be same logins in different
groups or different departments.
url
homePage(url:true)
validator
Usage: set to a Closure to use custom validation. A single or no parameter Closure receives the value, a
two-parameter Closure receives the value and object reference
even( validator: {
return (it % 2) == 0
})
password1( validator: {
val, obj ->
obj.properties['password2'] == val
})
magicNumber( validator:
someClosureWithTwoParameters)
Where feasible, Grails uses a domain class's constraints to influence the database columns generated for
the corresponding domain class property.
Consider the following example. Suppose we have a domain model with the following property.
String description
description varchar(255)
But perhaps the business rules for this domain class state that a description can be up to 1000 characters
in length. If that were the case, we'd likely define the column as follows if we were creating the table via
an SQL script.
description TEXT
Chances are we'd also want to have some application-based validation to make sure we don't exceed that
1000 character limit before we persist any records. In Grails, we achieve this validation via constraints.
We'd add the following constraint declaration to the domain class.
static constraints = {
description(maxSize:1000)
}
This constraint would provide both the application-based validation we want and it would also cause the
schema to be generated as shown above. Below is a description of the other constraints that influence
schema generation.
• maxSize
• size
If either constraint is defined, Grails sets the maximum column length based on the constraint value.
In general, it's not advisable to use both constraints on the same domain class property. However, if both
the maxSize constraint and the size constraint are defined, then Grails sets the column length to the
minimum of the maxSize constraint and the upper bound of the size constraint. (Grails uses the minimum
of the two, because any length that exceeds that minimum will result in a validation error.)
• min
• max
• range
Before 0.5 version minSize, maxSize and size constraint were also considered in schema generation
process for numeric properties
If the max constraint, the min constraint, or the range constraint is defined, Grails attempts to set the
column precision based on the constraint value. (The success of this attempted influence is largely
dependent on how Hibernate interacts with the underlying DBMS.)
In general, it's not advisable to combine the pair min/max and range constraints together on the same
domain class property. However, if both of these constraints is defined, then Grails uses the minimum
precision value from the constraints. (Grails uses the minimum of the two, because any length that
exceeds that minimum precision will result in a validation error.)
• scale
If the scale constraint is defined, then Grails attempts to set the column scale based on the constraint
value. This rule only applies to floating point numbers (i.e., java.lang.Float, java.Lang.Double,
java.lang.BigDecimal, or subclasses of java.lang.BigDecimal). (The success of this attempted influence is
largely dependent on how Hibernate interacts with the underlying DBMS.)
The constraints define the minimum/maximum numeric values, and Grails derives the maximum number
of digits for use in the precision. Keep in mind that specifying only one of min/max constraints will not
affect schema generation (since there could be large negative value of property with max:100, for
example), unless specified constraint value requires more digits than default Hibernate column precision
is (19 at the moment). For example...
someFloatValue(max:1000000, scale:3)
would yield:
but
someFloatValue(max:12345678901234567890, scale:5)
would yield:
and
would yield:
http://aboutgroovy.com/
http://www.copellafruitjuices.co.uk/ UK high-profile fruit juice brand
http://www.tropicana.co.uk/ UK site for leading orange juice brand
http://www.tropicana-go.com/ Children's drink brand
http://tvvoting.com/
http://www.cyathen.com
http://www.groovyblogs.org
http://entry.xmldo.jp/page2007 - Archive site - http://www.jagat.or.jp/page/2007/
http://groovy.canoo.com/errata/erratum
http://groovy.org.es
Chiumento Careers - http://www.chiumentocareers.co.uk/online/user/login
Success stories
User Documentation
Starting Up
1. Introduction
2. Installation
3. Quick Start
4. Configuration
5. IDE Integration
6. Auto Reloading
7. Logging
8. Command Line Tools
9. Frequently Asked Questions
10. Sample Applications
Domains
Services
1. Services
Controllers
1. Controllers
2. HTTP Method Restrictions
3. Scaffolding
4. URL Mapping
5. Command Objects
Views
Plugins
1. Available Plugins
2. Contribute a Plugin
3. The Plug-in Developers Guide
Testing
1. Unit Testing
2. Functional Testing
Advanced Topics
Grails Artifacts
Grails takes the separation of concerns approach splitting a Grails application in three layers or tiers:
Grails requires users to provide some of the artifacts in the above list. Configuration of these artifacts is
taken care of by Grails based on a number of conventions per artifact type.
Injection behavior
CountryService countryService
To enable injection by name add a "byName" property to the class and set it to true:
Configurational properties
When property names are reserved for the configuration of specific artifacts in Grails other properties
with the same name but not the same type are ignored.
class SomeService {
boolean transactional = false
String transactional = "false" // this property is ignored for configurational purposes.
}
Ajax Support
Introduction
Ajax stands for Asynchronous Javascript and XML and is the driving force behind the shift to richer web
applications. These types of applications in general are better suited to agile, dynamic frameworks written
in languages like Ruby and Groovy. Grails provides support for building Ajax applications through its Ajax
tab library for a full list of these see the Tag Library Reference.
Rails developers will be familiar with the tag library as there are equivalent helper methods in Rails for
most of Grails' Ajax tags.
One major difference with Grails' tags is that they are not tied to the Prototype library. For the Grails Ajax
tags to work you need to include a supported Ajax library within the "head" tag of your HTML document.
The tags will then "adapt" to the included library.
The tags can then be used as described in the following documentation without knowing the details of the
underlying implementation. This allows you to choose which library is best suited for your needs as each
provides its own benefits.
Installing Dojo
If you choose to use dojo because it is quite a large framework it does not come bundled with Grails and
requires installing. Luckily, Grails provides a target to do this for you. Type the following from the root of
grails install-dojo
Remote content can be loaded in a number of ways, the most commons way is through the "remoteLink"
tag. This tag allows the creation of HTML anchor tags that perform an asynchronous request and
optionally set the response in an element. The simplest way to create a remote link is as follows:
The above link sends an asynchronous request to the "delete" action of the current controller with an id
of "1". This is great, but usually you would want to provide some kind of feedback to the user as to what
has happened:
def delete = {
def b = Book.get( params.id )
b.delete()
render "Book ${b.id} was deleted"
}
<div id="message"></div>
<g:remoteLink action="delete" id="1" update="message">Delete Book</g:remoteLink>
The above example will call the action and set the contents of the "message" div to the response in this
case "Book 1 was deleted". This is done by the "update" attribute on the tag, which can also take a map
to indicate what should be updated on failure:
<div id="message"></div>
<div id="error"></div>
<g:remoteLink action="delete" id="1"
update="[success:'message',failure:'error']">Delete Book</g:remoteLink>
Handling Events
Specific javascript can be called if certain events occur, all the events start with the "on" prefix and allow
you to give feedback to the user where appropriate, or take other action:
The above code will execute the "showProgress()" function which may show a progress bar or whatever is
appropriate. Other events include:
An HTML form can also be submitted asynchronously in one of two ways. Firstly using the "formRemote"
tag which expects similar attributes to those for the "remoteLink" tag:
<g:formRemote url="[controller:'book',action:'delete']"
update="[success:'message',failure:'error']">
<input type="hidden" name="id" value="1" />
<input type="submit" value="Delete Book!" />
</g:formRemote >
Or alternatively you can use the "submitToRemote" button this allows some buttons to submit remotely
and some not depending on the action:
<form action="delete">
<input type="hidden" name="id" value="1" />
<g:submitToRemote action="delete" update="[success:'message',failure:'error']" />
</form>
Grails' render method is the perfect companion for creating Ajax responses in a number of ways. As an
example lets take a look at an example that retrieves the current date and time:
...
// controller action
def time = {
render "${new Date()}"
}
...
<g:remoteLink action="time" update="time">Get Time</g:remoteLink>
<div id="time">Time to be displayed here</div>
Here the render method is used to update the "time" div with the current time. However, the render
method can also be used to render markup:
...
// controller action
def time = {
render(contentType:'text/xml') {
But it gets even better, you can also render JSON responses using the same builder syntax:
...
// controller action
def time = {
render(builder:'json') {
time(new Date())
}
}
...
// resulting JSON response
{ time: "..." }
And if you want to leverage the OpenRico framework you can create OpenRico responses:
...
// controller action
def time = {
render(builder:'rico') {
element(id:'time') {
new Date()
}
}
}
...
// resulting Rico response
<ajax-response>
<response type="element" id="time">
... // current time here
</response>
</ajax-response>
When creating artifacts or using scaffolding, Grails uses templates to create the domain classes,
controllers, views etc. The default templates are part of the Grails distribution for out of the box
behaviour, but can be customized for project specific needs.
Scenario
Imagine you are using Action Interceptors for checking if an user is authenticated. In this case, (almost)
all controllers in your application need a before interceptor to do the authentication check. Easiest way to
do this is to create a SecuredBaseController containing the authentication interceptor
class SecuredBaseController {
def auth() {
if(!session.user) {
redirect(controller:'authentication',action:'login')
return false
}
}
}
You then can extend this SecuredBaseController in the controllers which need to be secured. Nothing new
so far. However, if almost 100% of your controllers need to be secured you will be extending this
SecuredBaseController over and over again. This does not only cost you time, but it also violates DRY.
Solution
As mentioned earlier, Grails uses templates for creating artifacts and scaffolding. The default template for
creating new controllers looks something like:
class @artifact.name@Controller {
def index = { }
}
When creating a new controller the @artifact.name@ will be replaced by the name you specified for the
new controller.
To secure all newly created controllers by default, we need to extend the SecuredBaseController in the
template:
def index = { }
}
Customizing templates
To customize the templates for you project you need to the install the templates:
grails install-templates
This will create the src/templates folder in your project which will contain various artifact and scaffolding
templates. These application specific templates can be customized and Grails will use them the next time
you create artificats or generate scaffolding. Grails will first check if the needed template exists within the
project, if it exists it will be used, otherwise the default template from the Grails distribution will be used.
This also means that templates which are not used can be removed from the project.
Note that both the artifact and scaffolding template folder contain a Controller template. So in the
example above both templates need to be changed to extend the SecuredBaseController.
Taking it further
Most projects will use the scaffolding generation only for prototyping or as a starting point, as the
generated views need to be changed to the layout requirements of the project. This can be a really time
consuming as it is not just extending some base class like the SecuredBaseController example above. You
can give your development time a huge boost by changing the list, show, create and edit scaffolding
templates before generating the views.
Auto Reloading
When a Grails application is executed via the 'grails run-app' command it is configured for auto-reloading
(development mode). This mode is disabled when a WAR is created via the 'grails war' command.
All Grails artifacts (controllers, tag libs, services etc.) are reloadable in Grails, however there are some
quirks:
• Services can currently only be reloaded if the 'transactional' property is set to false
• Domain Classes are re-mapped to the database at runtime. If the data source is configured to
auto-generate the database via the 'update' setting of the 'dbCreate' property it will do its best
effort to update the database. This process doesn't always go smoothly however and changing
domain classes occasionally require an application restart
Builders
The Hibernate Criteria Builder allows you to create queries that map to the Hibernate Criteria API. There
are equivalent builder nodes for most criterion within the Hibernate Expression class. For more info see
the Builders Reference
The builder can be used standalone by passing a persistent class and sessionFactory instance:
Or an instance can be retrieved via the createCriteria method of Grails domain class instances:
def c = Account.createCriteria()
def results = c {
like("holderFirstName", "Fred%")
and {
between("balance", 500, 1000)
eq("branch", "London")
}
maxResults(10)
order("holderLastName", "desc")
}
The results variable above cannot be typed as a List since it may actually be a proxy.
By default the builder returns a list of results, but can be forced to retrieve a unique result using the "get"
node:
def c = Account.createCriteria()
def a = c.get {
eq("number", 40830994)
}
OpenRico Builder
Grails provides support for the OpenRico project. See this document for more details on how OpenRico
handles response content. Using OpenRicoBuilder in controllers users can generate any response for
OpenRico requests, see the example below which uses the Google API to retrieve search results and then
creates an OpenRico ajax response.
It should be noted that at the moment, OpenRico requests are not handled by the Grails Ajax tags; there
is no OpenRico implementation in JavascriptTagLib.
Basics
Grails supports command line scripting using a Groovy ant wrapper called Gant
A Gant script is essentially a Groovy script that defines special "tasks" that can depend
on each other and invoke other tasks (just like Ant). The bonus is that your build files
are written in Groovy not XML.
The above of course is a very simple build, as your build gets more complex the power of Groovy
comes in handy. Note the use of the implicit "Ant" instance
You can use Ant from a Gant script using the implicit Ant variable. For instance consider this example
from the Compile.groovy Gant script in $GRAILS_HOME/script:
}
}
Here the script uses the Ant variable in combination with the sequential method which allows you to
omit the Ant prefix before each Ant call such as mkdir, javac and so on
The above will create a Gant script in $PROJECT_HOME/scripts, but this is not the only place
they can live as we will see in the next section.
grails my-script
What happens here is that Grails uses a convention to convert the command number (in lower case,
separated by
underscores) into the script name (in camel case) and then invokes the "default" task defined
within the script.
• $GRAILS_HOME/scripts
• $PROJECT_HOME/scripts
• $USER_HOME/.grails/scripts
• $PROJECT_HOME/plugins/*/scripts
If there are multiple scripts of the same name in these locations Grails will prompt you for
a choice of which one you want to execute. In other words, one script never overrides another.
Grails provides a number of scripts that are built in that can be re-used. Within the
$GRAILS_HOME/scripts directory you will find these. For example the Compile.groovy
script allows you to depend on Grails' compilation step or the Package.groovy script
allows you to depend on Grails' packaging step (which involves the generation of web.xml
To rely on these in your code you need to "include" them in your Gant script. The general
way to do this is via establishing the GRAILS_HOME environment variable:
grailsHome = Ant.project.properties."environment.GRAILS_HOME"
includeTargets << new File ( "${grailsHome}/scripts/Package.groovy" )
in the example above we include the Package.groovy script and depend on its package
task to ensure Grails is packaged correctly before executing our task.
Another useful task to depend on is within Init.groovy called classpath that does the job
of setting up the classpath using Groovy's RootLoader so that referencing within the lib, classes
or grails-app dir doesn't throw a ClassNotFoundException:
grailsHome = Ant.project.properties."environment.GRAILS_HOME"
includeTargets << new File ( "${grailsHome}/scripts/Init.groovy" )
If you don't depend on this task then an exception is thrown. Note that this is done because some
tasks need to delete classes (like Clean.groovy) and certain systems (like Windows) disallow this
if they have been loaded by the JVM
Sometimes it is useful to bootstrap the whole Grails environment inside a Grails script. This
is what some of the scaffolding and unit testing task do for example. To do this you can depend
on the Bootstrap.groovy script:
import org.springframework.orm.hibernate3.*
grailsHome = Ant.project.properties."environment.GRAILS_HOME"
includeTargets << new File ( "${grailsHome}/scripts/Bootstrap.groovy" )
def sf = ctx.getBean("sessionFactory")
What the Bootstrap.groovy script does is place a "application" variable which is an instance
of GrailsApplication and a "ctx" which is the Spring ApplicationContext
Grails ships with an extended version of the regular Groovy console. To run the console simply type the
following command from the root of a Grails project:
grails console
The console is a Swing GUI interface that lets you type arbitrary commands and execute them. It is a
good way to learn Grails and try out the various dynamic finders available on your domain model.
In addition to the console there is the interactive shell. It works similar to the console but with a text UI
only. To run the shell simply type the following command from the root of a Grails project:
grails shell
There are instructions on how to use it when it loads, but essentially you type in the commands you want
to execute separated by carriage returns and you then type go followed by a carriage return to execute
the commands.
General usage
Both console and shell are useful for working interactively with your Grails application:
Below is a transcript of an example session with a grails shell for a fictious book store application.
Packaging a WAR
grails war
By default this will package for a production environment you can change this by doing:
Command Objects
Grails Command Objects provide a simple mechanism to validate form fields that do not map directly to
domain objects. Using the validation constraints concept that applies to domain classes, including the
validate() method and "errors" dynamic property, Grails applies the concept of command objects to
controller actions. 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 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.
class LoginController {
def login = { LoginCommand cmd ->
if(cmd.hasErrors()) {
redirect(action:'loginForm')
}
else {
// do something else
}
}
}
The command object class may be defined under src/groovy/ or under grails-app/controllers/. The
command object class may also be defined in the same source file as the controller that uses it.
class LoginCommand {
String username
String password
static constraints = {
username(blank:false, minLength:6)
password(blank:false, minLength:6)
}
}
Configuration
Configuring Start-up
Programmatic start-up configuration can be added to a Grails application by creating one or many
"BootStrap" classes in the "%PROJECT_HOME%\grails-app\conf" directory:
class ExampleBootStrap {
The "init" closure (if it exists) is called on application load and the "destroy" closure (again if it exists) on
application exit
Warning
It is not guaranteed that destroy will be called unless the application exits gracefully (for example
by using the application server's shutdown command) so don't rely on it too much
See the Quick Start page for an example of using the "init" closure to build and save domain objects.
There are two alternatives when it comes to configuring DataSources for Grails (effective Grails 0.3)
1. Use the JDBC DataSource by defining (test/dev/prod) DataSource under grails-app/conf folder
2. Use JNDI dataSource in the spring/resources.xml folder of the application. Normally you would use
this if you want to re-use the existing dataSource settings of the J2EE Server you are running your
Grails application on.
Data source names should end with "DataSource". If no (available) data sources are found Grails will
start with an in-memory HSQLDB database with the database schema created at run-time. There are four
required String properties:
class HsqlDataSource {
String dbCreate = "update"
String url = "jdbc:hsqldb:hsql://localhost"
String driverClassName = "org.hsqldb.jdbcDriver"
String username = "sa"
String password = ""
}
Environments
Warning
When running as prod, you must be sure to copy the grails-app/views directory into
web-app/WEB-INF/grails-app/, otherwise grails won't be able to find any of your views. Note that
you must do this _after_ you have started your app.
These options are also available when packaging the application as a WAR file, although in this case the
default data source used is production:
grails war // Packages the application with the "production" data source
grails dev war // Packages the application with the "development" data source
grails prod war // Packages the application with the "production" data source
If you have other environments you need to target you can create another data source that follows the
convention. For example BookDataSource and then start Grails app as follows:
Connection Pooling
By default Grails is configured to attempt to update or create the database on application load this is
configured with the "dbCreate" property:
If this property is removed the database will have to be created manually or by a separate process. Other
possible values for this property are "create" and "create-drop".
SQL Logging
To enable SQL logging in your grails application add the following property to the Grails data source file:
To set a custom dialect for Hibernate to use add a 'dialect' property to the data source referencing the
dialect class to use:
Hibernate has also been tested with and is believed to be compatible with current versions of:
• Apache Derby
• HP NonStop SQL/MX 2.0 (requires Dialect from HP)
• Firebird (1.5 with JayBird 1.01 tested)
• FrontBase
• Informix
• Ingres
• Interbase (6.0.1 tested)
• Mckoi SQL
• Pointbase Embedded (4.3 tested)
• Progress 9
Using MySQL
http://www.mysql.com/products/connector/j/
Unpack the archive and copy the mysql*.jar (not the debug jar) to lib
in your grails application directory.
class DevelopmentDataSource {
boolean pooling = true
String dbCreate = "create-drop"
String url = "jdbc:mysql://localhost/yourDB"
String driverClassName = "com.mysql.jdbc.Driver"
String username = "yourUser"
String password = "yourPassword"
}
Normally you would use this approach if running inside a J2EE server which has its own JNDI entries for
the Database already set up, so you could re-use the connection settings. If there is a bean by name
"dataSource" with class "org.springframework.jndi.JndiObjectFactoryBean", Grails runtime would take
this entry instead of the grails-app/conf/ datasources.
An example entry for dataSource bean in the resources.xml would be as following. Of course you have to
change the property jndiName's value appropriately.
Occasionally you may want the application name to be different from the project's directory name. This
affects the URI used when testing locally, and the name of JARs produced.
Edit the application.properties file in your project directory and change the value of app.name
Grails Controllers
What is a controller?
A controller handles requests and creates or prepares the response. They can generate the response or
delegate to a view. To create a controller simply create a class whose name ends with "Controller" and
place it within the "grails-app/controllers" directory.
The first part of your controller name is mapped to a URI and each action defined within your controller
maps to URI within the controller name URI.
If you're lazy you can create a controller using the "create-controller" target which will prompt for the
name of your controller:
grails create-controller
BookController maps to the <...>/book URI. Note that grails has done no special configuration in the
background, all this is doing is creating you a controller from a template.
Creating Actions
A controller can have multiple closure properties. Each of these properties maps to a URI:
class BookController {
def list = {
// do controller logic
// create model
return model
};
}
Controller actions may accept command object parameters. See the Command Object documentation
for details.
There are 2 ways to set the default action (ie the action that is executed if no only the controller name is
included in the uri), the simplest way is to merely create an action called "index":
def index = {
redirect(action:list)
}
By default all controller actions are accessible using any HTTP request method (GET, PUT, POST, etc...).
The documentation for HTTP Method Restrictions explains how to restrict access to certain actions.
Every controller has a number of properties inject into them at runtime, these make it possible to access
the request, session etc. For a full reference on these please see the Dynamic Methods Reference
class BookController {
def find = {
def findBy = params["findBy"]
def appContext = servletContext["appContext"]
def loggedUser = session["logged_user"]
// do stuff
// return model
return model
};
}
Flash scope is a concept introduction by Rails and essentially is a temporary store for attributes that
should be available for the next request and the request only, after which they are cleared. This is useful
def delete = {
def b = Book.get( params['id'] )
if(!b) {
flash['message'] = "User not found for id ${params['id']}"
redirect(action:list)
}
... // remaining code
}
Request parameters get passed into web applications as strings, causing a typical scenario of having to
convert each string value into its equivalent object representation. With Grails domain classes this is
made simple by the "properties" property:
def save = {
def b = new Book()
b.properties = params
b.save()
}
In the above example with one line of code the request parameters are auto-magically converted and set
on the instance of Book. If you're using a command object or some other object that you want to bind
data to you can use the "bindData" method present in controllers:
A model is essentially a map that the view uses when rendering. There are a couple of ways to return a
model, the first way is to explicitly return a map instance:
def show = {
def b = Book.get( params['id'] )
return [ book : b ]
}
If no explicit model is returned the controller's properties will be used as the model thus allowing you to
write code like this:
class BookController {
List books
List authors
def list = {
books = Book.list()
authors = Author.list()
}
}
In the above example the "books" and "authors" properties will be available in the view. A more
Rendering a Response
Sometimes its easier (typically with Ajax applications) to render snippets of text or code to the response
directly from the controller. For this the highly flexible "render" method can be used:
The above code writes the text "Hello World!" to the response, other examples include:
Actions can be redirected using the "redirect" method present in all controllers:
class OverviewController {
def login = {}
def find = {
if(!session["logged_user"])
redirect(action:login)
.....
};
}
The redirect method expects either another closure within the same controller class, the name of a
controller and action in another class, a URI for a resource in the webapp or a full URL:
Parameters can be optionally passed from one action to the next using the params argument of the
method:
redirect(action:myaction, params:["myparam":"myvalue"])
These params are made available through the "params" dynamic property that also 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 used.
class ChainController {
def firstInChain = {
chain(action:secondInChain,model:["step1":new Object()])
}
def secondInChain = {
chain(action:thirdInChain,model:["step2":new Object()])
};
def thirdInChain= {
return ["step3":new Object()])
};
}
The model can be accessed in subsequent controller actions in the chain via the "chainModel" map. This
dynamic property only exists in actions following the call to "chain":
class ChainController {
def nextInChain = {
def model = chainModel["myModel"]
.....
};
}
Like the "redirect" method you can also pass parameters to the chain method:
Action Interceptors
Introduction
Often it is useful to intercept processing based on either request, session or application state. This can be
achieved via action interceptors. There are currently 2 types of interceptors: before and after.
Before Interception
The 'before' interceptor intercepts processing before the action is executed. If it returns 'false' then the
following action will not be executed. The interceptor can be defined for all actions as follows:
def beforeInterceptor = {
println "Tracing action ${actionUri}"
}
The above will be executed before all actions and does not interfere with processing. A common use case
is however for authentication:
The above code defines a method called 'auth'. A method is used so that it is not exposed as an action to
the outside world (i.e. it is private). The 'beforeInterceptor' then defines an interceptor that is used on all
actions 'except' the login action and is told to execute the 'auth' method. The 'auth' method is referenced
using Groovy's method pointer syntax, within the method itself it detects whether there is a user in the
session otherwise it redirects to the login action and returns false, instruction the intercepted action not
to be processed.
After Interception
To define an interceptor that is executed after an action use the 'afterInterceptor' property:
The after interceptor takes the resulting model as an argument and can hence perform post manipulation
of the model or response.
Interception Conditions
Rails users will be familiar with the authentication example and how the 'except' condition was used when
executing the interceptor (interceptors are called 'filters' in Rails, this terminology conflicts with the
servlet filter terminology in Java land):
This executes the interceptor for all actions except the specified action. A list of actions can also be
defined as follows:
The other supported condition is 'only', this executes the interceptor for only the specified actions:
To upload a file the first step is to create a multipart form like the one below:
There are then a number of ways to handle the file upload. The first way is to work with the Spring
MultipartFile instance directly:
def upload = {
def f = request.getFile('myFile')
if(!f.empty) {
f.transferTo( new File('someotherloc') )
}
else {
flash.message = 'file cannot be empty'
redirect(action:'uploadForm')
}
}
This is clearly handy for doing transfers to other destinations and manipulating the file directly (you can
also open an InputStream, see javadoc). The next way
to deal with file uploads is to bind the file's contents to a domain class or command bean. Lets look at a
domain class example say you have an 'Image' domain class like the below:
class Image {
byte[] myFile
}
The contents of the file will automatically be converted into a byte[] and set on the image domain class.
It is also possible to set the contents of the file as a string by
changing the type of the 'myFile' property on the image to a String type:
class Image {
String myFile
}
The final way to do this is via the 'bindData' method which you can use in combination with a command
object. Say we have a command object like the below:
class UploadCommand {
byte[] myFile
}
def upload = {
def uc = new UploadCommand()
bindData(uc, params)
assert uc.myFile != null
}
Controllers may use services to delegate requests to business logic. To have these resources injected add
corresponding properties to the controller.
Important here is the name of the property, not it's type. You could also write it without untyped.
def countryService
If you do want to inject services by type, you can add a property called byName to your controller.
class CountryController {
def byName = false
def CountryService whateverNameHere
}
Overview
As of version 0.4 Grails adds support for dynamic encode/decode methods. A set of standard codecs are
bundled with Grails. Grails also supports a simple mechanism for developers to contribute their own
codecs that will be recognized at runtime.
Codec Classes
A Grails codec class is a class that may contain an encode closure, a decode closure or both. When a
Grails application starts up the Grails framework will dynamically load codecs from the grails-app/utils/
directory.
The framework will look under grails-app/utils/ for class names that end with the word 'Codec'. For
example one of the standard codecs that ship with Grails is grails-app/utils/HTMLCodec.groovy
If a codec contains an encode closure Grails will create a dynamic encode method and add that method to
the String class with a name representing the codec that defined the encode closure. For example, the
HTMLCodec class defines an encode closure so Grails will attach that closure to the String class with the
name encodeAsHTML.
The HTMLCodec and URLCodec classes also define a decode closure so Grails will attach those closures to
the String class with the names decodeHTML and decodeURL. Dynamic codec methods may be invoked
from anywhere in a Grails application. For example, consider a case where a report contains a property
called 'description' and that description may contain special characters that need to be escaped to be
presented in an HTML document. One way to deal with that in a GSP is to encode the description
property using the dynamic encode method as shown below:
${report.description.encodeAsHTML()}
Standard Codecs
HTMLCodec
This codec perfoms HTML escaping and unescaping, so that values you provide can be rendered safely in
Example of usage:
Note that the HTML encoding does not re-encode apostrophe/single quote so you must use double quotes
on attribute values to avoid text with apostrophes messing up your page.
URLCodec
URL encoding is required when creating URLs in links or form actions, or any time data may be used to
create a URL. It prevents illegal characters getting into the URL to change its meaning, for example a
"Apple & Blackberry" is not going to work well as a parameter in a GET request as the ampersand will
break the parsing of parameters.
Example of usage:
Base64Codec
JavaScriptCodec
Example of usage:
Custom Codecs
Applications may define their own codecs and Grails will load them along with the standard codecs. A
custom codec class must be defined in the grails-app/utils/ directory and the class name must end with
'Codec'. The codec may contain a static encode closure, a static decode closure or both. The closure
should expect a single argument which will be the object that the dynamic method was invoked on.
${lastName.encodeAsPigLatin()}
Grails has a wide range of custom tags built in for both JSP and GSP (see the Tag Library Reference
here), however Grails also allows the creation of simple, logical, and iterative custom tags through its
simple dynamic tag library mechanism.
Contribute!
Got a tag that you would like to share with the rest of the Grails developers? Contribute a tag!
The benefit of Grails' tags is that they require no additional configuration, no updating of TLD descriptors,
and can be auto-reloaded at runtime without a server restart. This makes developing tags feel as if you
were just developing another part of the view and increases their usefulness tenfold.
Warning
Grails Tag libraries require a little extra work to integrate into JSP and are more seamlessly
integrated into GSP because of its dynamic nature. See the last section for how to use grails tags
from JSP
Simple tags
To create new tags open the "grails-app/taglib/ApplicationTagLib.groovy" file or create a new class ending
in "TagLib". To create a simple tag add a new closure property that takes 1 argument which are the
attributes of the tag:
To call your tag your from a GSP page use the "g" prefix followed by the tag property name:
Logical tags
You can also create logical tags by using a closure syntax that takes 2 arguments, the attributes of the
The tag above checks if the user is an administrator and invokes the body of the tag if he/she is:
<g:isAdmin user="${myUser}">
// some restricted content
</g:isAdmin>
Iterative tags
<g:repeat times="3">
<p>Repeat this 3 times! Current repeat = ${it}</p>
</g:repeat>
Grails provides a special method that allows building of markup (a common usecase in tags). To do so
you invoke the 'mkp' method passing a closure with the markup you want rendered:
GSP tags can also be used in Groovy expressions in the GSP page. For example, the hasErrors tag can be
The last argument of the method is taken as the body of the tag. Or you can pass a closure that returns a
string:
<%=
hasErrors(bean:book,field:'title') {
'errors'
} %>
To use a Grails taglib definition in JSP you can use the JSP "invokeTag" tag which will call a tag defined in
the Grail tag library:
If you want your tags to appear like normal JSP tags, here's what you need to do:
package com.mycompany.taglib;
public class IncludeJsTag extends JspInvokeGrailsTagLibTag {
public static final String TAG_NAME = "includeJs";
public IncludeJsTag() {
super.setName(TAG_NAME);
}
}
2) JSP requires declarative tag library definition files (TLD) for each tag, to do this modify the
"web-app/WEB-INF/tld/grails.tld" file and add the necessary entries that point to your class:
<tag>
<name>includeJs</name>
3) You can then call your tag from JSP like a normal JSP tag:
Functional Testing
In addition to unit testing, Grails supports functional testing of your web application.
If you want to try out webtest very quickly, you can create a new project with create-app, create a
domain class and then "generate-all" this domain class. Then generate the test layout with "create
webtest" and generate the webtest itself with "generate-webtest". You can then run the tests with
"run-webtest". Note that the scaffolded webtest will not work out of the box if you use dynamic
scaffolding of your controller. Just use generative scaffolding for the controller instead.
grails create-webtest
grails generate-webtest
• creates an initial webtest for the default views and controllers of the domain class
• tests basic operations: list, create, delete through the web GUI
grails run-webtest
When on Windows, the browser is automatically opened on the HTML report. It will present you a header
with summarized and statistical data like below.
A trailing section shows details about all operations effected during the test (excerpt).
Test First
WebTests can even be started if the server is not running. You can actually run the test before
you have coded anything.
In this case the report will show a lot of failed tests but that's helpful anyways. You'll see what
behavior the tests expect and how the report is generated.
After creation and generation of a test for the mydomain domain class, you'll find the following files and
folders below your application folder:
myapp
+-- webtest
+-- conf (webtest.properties)
+-- reports (readme.txt)
+-- tests (TestSuite.groovy, MydomainTest.groovy)
def testMydomainListNewDelete() {
webtest('Mydomain basic operations: view list, create new entry, back to view, delete,
view'){
invoke(url:'mydomain')
verifyText(text:'Home')
clickLink(label:'New Mydomain')
verifyText(text:'Create Mydomain')
clickButton(label:'Create')
// more ...
}
There are multiple steps like invoke, clickButton, verifyXXX, etc. that make up the test specification.
Find the full list of available steps, their parameters, a comprehensive description, and examples under
WebTest Docs.
The online documentation lists these steps in their ANT notation (i.e. XML). This exactly maps to the
Adapt the lines in MydomainTest.groovy to match the expected behavior of your webapp. If you have any
bootstrapped data, your tests can rely on this data being available when starting the tests.
More Tests
You can have many tests like MydomainTest.groovy in the tests directory or its subdirectories.
Every such test must extend grails.util.WebTest and provide a suite method that calls each available
test method. In subdirectories, tests must have the according package statements.
Tests will automatically be picked up by TestSuite.groovy. You can customize this logic to define your
own suite (see its inlined comments on how to do that).
Customization of the suite is sometimes needed to assert a special sequence of test execution or to
restrict the test execution to a subset of availabable tests.
groovy testing
Dierk Koenig
Introduction
Domain classes are core to any business application. They hold state about business processes and
hopefully also implement behavior. They are linked together through relationships, either one-to-one or
one-to-many.
GORM is Grails' object relational mapping (ORM) implementation. Under the hood it uses Hibernate 3 (an
extremely popular and flexible open source ORM solution) but because of the dynamic nature of Groovy,
the fact that it supports both static and dynamic typing and the convention of Grails there is less
configuration involved in creating Grails domain classes.
You can also write Grails domain class in Java see the section on Hibernate Integration for how to write
Grails domain classes in Java but still use dynamic persistent methods.
More Information
Sets of objects
By default when you define a relationship with GORM it is a java.util.Set which is an unordered collection
that cannot contain duplicates. In other words when you have:
class Author {
static hasMany = [books:Book]
}
The books property that GORM injects is a java.util.Set. The problem with this is there is no ordering
when accessing the collection, which may not be what you want. To get custom ordering you can say that
the set is a SortedSet:
class Author {
SortedSet books
static hasMany = [books:Book]
}
In this case a java.util.SortedSet implementation is used which means you have to implement
java.lang.Comparable in your Book class:
int compareTo(obj) {
releaseDate.compareTo(obj.releaseDate)
}
}
The result of the above class is that the Book instances in the books collections of the Author class will be
ordered by their release date.
If you simply want to be able to keep objects in the order which they were added and to be able to
reference them by index like an array you can define your collection type as a List:
class Author {
List books
static hasMany = [books:Book]
In this case when you add new elements to the books collection the order is retained in a sequential list
indexed from 0 so you can do:
The way this works at the database level is Hibernate creates a books_idx column where it saves the
index of the elements in the collection in order to retain this order at the db level.
If you want a simple map of string/value pairs GORM can map this with the following:
class Author {
Map books // my of ISBN:book names
}
In this case the key and value of the map MUST be strings.
class Book {
Map authors
static hasMany = [authors:Author]
}
The static hasMany property defines the type of the elements within the Map. The keys for the map MUST
be strings.
Basics
A domain class in Grails is essentially a normal Groovy class. It looks like any other class except at
runtime it gets injected with 2 additional properties: an "id" property and a "version" property:
class Book {
String title
}
To help you get started you can run the following convenience target from the root of your Grails project:
grails create-domain-class
By default all properties are both persistent and required, to change that you can define List properties
called "optionals" and "transients". Transient properties are never written to the database. They don't
have a corresponding column in the database. Optional properties have corresponding columns in the
database that are nullable.
class Book {
static optionals = [ "releaseDate" ]
static transients = [ "digitalCopy" ]
Author author
String title
String author
Date releaseDate
File digitalCopy
}
Default values
You can also create default values for properties that you don't want to make optional. This is done like
so:
class Book {
//omitted code...
You can change the name of the table used when doing the mapping using the withTable property:
class Book {
Be careful with SQL reserved words. The code bellow will have problem because of the "order" attribute.
"order" is a SQL reserved word:
class Book {
Integer order
}
CRUD Operations
Grails domain classes use dynamic persistent methods to facilitate CRUD (Create/Read/Update/Delete)
operations on persistent classes:
Create
To create entries in the database, domain class instances support a "save" method which cascades to the
instance relationships. In the example below we only call "save" on the author and both the Author and
Book instances are persisted:
// persist
a.save()
In this case we're having to create both sides of the relationship manually. GORM will manage the
persistence of your object model to the database, but won't manage the relationships for you.
However since 0.3 Grails provides more intelligent relationship management that will manage bidrectional
relationship state through dynamic methods:
This will add several books to the Author plus make sure the author property on each Book is set thus
managing this burden for you.
Read
Grails supports a number of ways of retrieving domain class instances, for more detail on querying see
the section on Domain Class Querying, however to retrieve an instance if the "id" is known you can use
the "get" static method:
Book.get(1)
Or to find all books the "findAll", "list" or "listOrderByX" static methods can be used:
Update
The symantics of updating differ from that of saving a domain class. It is possible to update without
explicitly calling "save" with the changes automatically being persisted if no exceptions occur:
def b = Book.get(1)
b.releaseDate = new Date()
This behaviour is not always desired however paricularily when combined with validation constraints (ie
you don't want your domain object saved if it is not validated). Therefore if you explicity call "save" and
the object is not valid changes will not be persisted:
def b = Book.get(1)
b.title = null // can't have a null title
b.save() // won't save as fails to validate
It is sometimes handy though to make changes to your domain model programmatically if validation fails.
In this way the symantics of the "validate" method differ as it won't discard the changes if validation fails:
def b = Book.get(1)
b.publisher = "Print It"
if(!b.validate()) {
b.publisher = Publisher.DEFAULT
}
In the above case changes will still be persisted even though validation failed during the "validate"
method. If you want the "validate" method to not persist changes if it fails to validate you can pass a
boolean "true" argument:
b.validate(true)
Alternatively, if you want to explicitly control if changes are persisted you can use the "discard" method
that when called will discard any changes:
def b = Book.get(1)
b.title = "A New Title"
Delete
Domain class instances can be removed from the database by using the "delete" instance method:
Creating Relationships
Relationships define how domain classes interact with each other. Unless specified explicitly at both ends,
a relationship exists only in the direction it is defined.
One-to-one
class Face {
Nose nose
}
This sets up a relationship between a Face and a single Nose. If the Face is deleted, the Nose will be
deleted also. This relationship is unidirectional currently, unless you add a reference in reverse from the
Nose:
class Nose {
Face face
}
In this scenario, deletion of either object will result in the deletion of the other. If this were part of a 3D
modelling system however noses might be part of a library of features, and as such deletion of the Face
referencing the nose should not delete the Nose. You just need to tell Grails that a Face "belongs" to a
Nose instead. While the terminology in this example is slightly unusual it is easy to understand:
class Face {
static belongsTo = Nose
Nose nose
This tells Grails that the Nose is the important piece here and that we are simply "using" it and do not
own it.
myFace.nose = bigNose
bigNose.face = myFace
You must implement this yourself, typically by implementing Face.setNose(Nose newNose) so that
it assigns "this" to newNose.face.
Defining a one-to-many relationship is a simple matter of adding the mapping to the "hasMany" map.
Defining a property of type Set is optional (before Grails 0.3 you needed to have "Set books" as well as
the "hasMany ..."). If you want, you can define the property like this: "Set books = new HashSet()"
class Author {
static hasMany = [ books : Book ]
String name
}
The ownership in a relationship is implied by a reference to (i.e. property of the type of) another domain
class or by inclusion of the owned class in the hasMany map, detailed below.
One of the main features of Groovy is its support for static typing which means one-to-one and
many-to-one relationships require no additions to the "relationships" map:
class Book {
Author author
String title
}
For one-to-many's the owning side is assumed to be the "one" side of the relationship (in the above
example this would be "Author.groovy"), but if you create a one-to-one relationship it is important to
define the owning side of the relationship. For example if we had an Author class which had no
relationship to the Book class (ie in a one-to-one scenario) it would be assumed that the book class
"owned" the author which clearly is not the case!
The implications of this is that if you delete an instance of Book the delete operation will also delete the
Author, not exactly the desired effect. To define the belongings side of one-to-one or many-to-one
relationship we use the "belongsTo" property:
Author author
String title
}
class Author {
static hasMany = [books:Book, coBooks:Book]
static mappedBy = [books:"mainAuthor", coBooks:"coAuthor"]
String name
}
class Book {
static belongsTo = Author
Author mainAuthor
Author coAuthor
String title
}
As you can see we have to use mappedBy for this case, to let the grails know how to map the fields since
the hasMany map contains duplicate class.
A class can also belong to multiple related classes like this:
In other words:
Many-to-many relationships can be defined by having a hasMany on each side of the relationship with at
least one side having a belongsTo property:
class Book {
static belongsTo = Author
static hasMany = [authors:Author]
}
class Author {
static hasMany = [books:Book]
}
new Author(..)
.addBook(new Book(..))
.save()
Since Author is the owner of this relationship this is possible, however you cannot add a new Author to a
Book and save the Book expecting the update to cascade as only the owning side can cascade updates in
this way.
Also, by default only saves and updates are cascaded from the owner and not deletes. The implication
here is that you must explicitly delete a Book to remove it otherwise you will get orphaned instances.
See the Author/Book example and files on the Hibernate Integration page.
It is also possible to define components with GORM. In this case the association will not map to a
separate table, but instead be in the same table as the owner of the composition. For example take the
following classes:
class Person {
String name
Address homeAddress
Address workAddress
static embedded = ['homeAddress', 'workAddress']
}
class Address {
String houseNumber
String postCode
}
In this even though we have two classes the homeAddress and workAddress properties map to the
person table in the following way:
Person Table
id name
home_address_house_number
home_address_post_code
work_address_house_number
work_address_post_code
As you can see the Person class is composed to two Address classes at the domain model and database
level.
Relationship Summary
Managing Relationships
As of 0.5 this syntax is deprecated! See next section for migration path.
Since 0.3, Grails provides quite a few methods to easy relationship management. Firstly if you have a
one-to-many relationship such as the Author-Book relationship defined below:
class Author {
String name
static hasMany = [books:Book]
}
class Book {
String title
Author author
static belongsTo = Author
}
You can use the dynamic addBook method on author to ease relationship management:
The addBook method is available at runtime and uses the class name of the Book to automatically
establish the relationship. If it is bidirectional it will also make sure that the author property of the Book
instance is set.
If you have more than one one-to-many relationship defined for the same class:
class Author {
String name
static hasMany = [fiction:Book, nonFiction:Book]
}
You can use the add method which takes a to argument which defines which collection to add the book
to:
class Author {
String name
static hasMany = [books:Book]
}
class Book {
String title
Author author
static belongsTo = Author
}
You can use the dynamic addToBooks method on author to ease relationship management:
The addToBooks method is available at runtime and uses the name of the books collection to
automatically establish the relationship. If it is bidirectional it will also make sure that the author
property of the Book instance is set.
Conversely there is also a removeFromBooks method for removing a Book from a relationship:
author.removeFromBooks(myBook)
Mapping Inheritance
GORM uses table-per-heirarchy inheritance which essentially means the parent and all sub-classes share
the same table:
class Content {
String author
}
class BlogEntry extends Content {
URL url
}
class Book extends Content {
String ISBN
}
class PodCast extends Content {
byte[] audioStream
}
def content = Content.findAll() // find all blog entries, books and pod casts
content = Content.findAllByAuthor('Joe Bloggs') // find all by author
Technical note for those interested: Under the covers, only one table is used in the
table-per-hierarchy model. A class column specifies the subclass and any fields in the subclasses
are included on the same table. Subclass fields cannot be "required" because the underlying
columns need to be nullable for the other subclasses. This doesn't however prevent you from
using Validation constraints to ensure that subclass fields are "required".
There are several ways to query for domain class instances, one of them being via Grails dynamic
methods, from more details see DomainClass Dynamic Methods:
results =
Book
.findByTitleLike("Harry Pot%")
results =
Book
.findByReleaseDateBetween( firstDate, secondDate )
results =
Book
.findByReleaseDateGreaterThan( someDate )
results =
Book
.findByTitleLikeOrReleaseDateLessThan( "%Something%", someDate )
// find by relationship
results = Book.findAllByAuthor( Author.get(1) )
Querying by example
Just pass an example of the domain object you would like to find to the find() method.
For more advanced queries or querying across objects graphs you can use Criteria (for a full reference
see the section on Builders):
def c = Book.createCriteria()
def results = c {
like("author.name", "Stephen%")
between("releaseDate", firstDate, secondDate )
}
def results =
Book.findAll("from Book as b where b.title like 'Lord of the%'")
def results =
Book.findAll("from Book as b where b.title like ?", ["The Shi%"])
Be careful with Groovy multi-line strings: if they contain any newlines, then the query will not work. So
for example this:
Note The space after "Author as a" is important, otherwise the string would look like "...Author as
awhere b.author...".
Sometimes is desireable to query objects that relate to each other without lazy=true , so SQL is
optimized and there is no n+1 SQL SELECT queries. To do that you can:
2) You can also try with Criteria Builder, with something like this:
import org.hibernate.FetchMode as FM
// ......
def c2 = Task.createCriteria()
def tasks = c2.list{
eq("assignee.id", task.assignee.id)
maxResults(new Integer(params.max))
firstResult(new Integer(params.offset))
fetchMode('assignee', FM.EAGER)
fetchMode('project', FM.EAGER)
The code above has not been really tested, so if someone verifies it works for EAGER fetching, please
delete this text line here. (justo wrote this Querying with Eager Fetching section as someone in the
list suggested).
3) You can use hibernate .hbm files to mapp relations using lazy=false.
GSP Reference
Example
Reference
• Variables available
• Page properties
• Invoking tags and passing attributes
• Inline Groovy script
Example
Reference
Variables available
There are a number of variables available to all pages. These are similar to those used in Java Server
Pages (JSP).
• application
• flash
• out
• params
• request
• response
• session
application
This refers to the servletContext, which can be useful for accessing attributes shared across the whole
application (not per-request).
Example:
Imagine you have set a versionNumber attribute on the servletContext in your ApplicationBootStap's
init() closure. You can then display this in any page:
flash
out
params
request
response
Hibernate integration
If GORM (Grails Object Relational Mapping) is not flexible enough for your liking you can alternatively
map your domain class using Hibernate. To do this create a "hibernate.cfg.xml" file in the
"%PROJECT_HOME%\hibernate" directory of your project and the corresponding Hbm mapping xml file
for your domain class. For more info on how to do this read the documentation on mapping on the
Hibernate Website
This will allow you to map Grails domain classes onto a wider range of legacy systems and be more
flexible in the creation of your database schema.
Grails also allows you to write your domain model in Java or re-use an existing domain model that has
been mapped using Hibernate. all you have to do is place the necessary "hibernate.cfg.xml" file and
corresponding mappings files in the "%PROJECT_HOME%\hibernate" directory.
You will still be able to call all of the dynamic persistent and query methods allowed in GORM!
Grails also supports creating domain classes mapped with Hibernate's Java 5.0 Annotations support. To
do so you need to tell Grails that you are using an annotation configuration by setting the "configClass" in
your data source project as follows:
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
class DevelopmentDataSource {
def configClass = GrailsAnnotationConfiguration.class
... // remaining properties
}
That's it for the configuration! Oh and make sure you have Java 5.0 installed as this is required to use
annotations. Now to create an annotated class we simply create a new Java class and use the annotations
defined as part of the EJB 3.0 spec (for more info on this see the Hibernate Annotations Docs:
package com.books;
@Entity
public class Book {
private Long id;
@Id
@GeneratedValue
public Long getId() {
return id;
}
Once thats done we need to register the class with the Hibernate sessionFactory, to do so we add entries
to the "%PROJECT_HOME%/hibernate/hibernate.cfg.xml" file as follows:
<hibernate-configuration>
<session-factory>
<mapping package="com.books" />
<mapping class="com.books.Book" />
</session-factory>
</hibernate-configuration>
And that's it! When Grails loads it will register the necessary dynamic methods with the class! To see
what else you can do with a Hibernate domain class see the section on Scaffolding
Note when you generate views, or controllers you need to specify the entire package name ie
com.books.Book, currently (v 0.3) there are mistakes in the generated code. Specifically the static
methods need to be fully qualified (add the package name)
You can use Grails dynamic methods (for example, findBy*()) and properties for domain classes in an
application written in Java that uses Hibernate for object-relational mapping (ORM). Simply embed into
your application the Groovy scripts that harness Grails dynamic functionality, which results in short
readable scripts that query for data (DML operations currently do not work).
1. grails
2. groovy-all
3. spring
4. commons-lang
You can find these JAR files within your Grails installation directory--more specifically, the
<GRAILS_HOME>/lib and <GRAILS_HOME>/dist directories.
import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;
import org.hibernate.SessionFactory;
import org.codehaus.groovy.grails.commons.DefaultGrailsApplication;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsHibernateUtil;
DefaultGrailsApplication defaultApplication;
SessionFactory sessionFactory;
The HibernateUtil class manages a SessionFactory so that I have to create it only once. The source code
for this class is taken from the Hibernate documentation.
import org.hibernate.*;
import org.hibernate.cfg.*;
static {
try {
// Create the SessionFactory from hibernate.cfg.xml
sessionFactory = new Configuration ().configure ().buildSessionFactory ();
}
catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed.
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError (ex);
}
}
Now you are ready to execute Groovy scripts that use the dynamic methods:
String[] scriptLocations;
GroovyScriptEngine engine;
Binding binding;
try {
Object obj = engine.run ("Foobar.groovy", binding);
// ...
import foil.MillRoll
return MillRoll.list()
which would give you a List with all persisted "foil.MillRoll" Objects.
You can define custom user hibernate types to map database fields in non-standard ways.
For example, here's a custom UserType that maps a varchar2(1) field wich allows values of '0' and '1' tu
a boolean instead than String.
package persistence;
import org.hibernate.*;
import org.hibernate.usertype.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.*;
import java.io.Serializable;
You can then use the new type in your .hbm.xml hibernate mapping file:
Other Resources
Here is an example with a many-to-many relationship: an author can write several books and a book can
be written by several authors. The relationship will be managed from the author's side: a book can be
added or removed from the author's list of books.
From the book GSP pages it looks like an author can be added/removed from the book side, but in
reality, the author of the current book gets his/her book list updated. See the book controller for more
details. Following are the Hibernate files and domain class files for Author and Book, the data source
config file and some excerpts of the controllers.
The zip file contains all the files to build the example. The database used is mySQL and the
"\conf\DevelopmentDataSource.groovy" file set accordingly. Change it for your database, don't forget to
include the JBDC driver in your placing the driver jar file in the %PROJECT_HOME%\lib directory. In this
example: "%PROJECT_HOME%\lib\mysql-connector\mysql-connector-java-3.1.12-bin.jar". IMPORTANT:
The version of Grails used is 0.3-SNAPSHOT of 17-Oct-06.
%PROJECT_HOME%\hibernate\hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<mapping resource="Book.hbm.xml"/>
<mapping resource="Author.hbm.xml"/>
</session-factory>
</hibernate-configuration>
%PROJECT_HOME%\hibernate\Author.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Author" table="author">
<id name="id" column="id" unsaved-value="null">
<generator class="native"></generator>
</id>
%PROJECT_HOME%\hibernate\Book.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="Book" table="book">
<id name="id" column="id" unsaved-value="null">
<generator class="native"></generator>
</id>
%PROJECT_HOME%\grails-app\conf\DevelopmentDataSource.groovy
class DevelopmentDataSource {
boolean pooling = true
String dbCreate = "create-drop"
String url = "jdbc:mysql://localhost/library"
String driverClassName = "com.mysql.jdbc.Driver"
String username = "root"
String password = ""
}
%PROJECT_HOME%\conf\ApplicationBootStrap.groovy
class ApplicationBootStrap {
Closure init =
{
def book
book = new Book(title: 'Moto')
book.save()
book = new Book(title: 'Auto')
book.save()
book = new Book(title: 'Cooking')
book.save()
book = new Book(title: 'Windsurfing')
book.save()
%PROJECT_HOME%\grails-app\controllers\AuthorController.groovy
class AuthorController {
...
def edit = {
def author = Author.get( params.id )
if (!author) {
flash.message = "Author not found with id ${params.id}"
redirect(action:list)
}
else {
def availableBooks = Book.list(max:20,order:'asc')
def authorBooks = author.books
availableBooks = availableBooks - authorBooks;
return [author : author , availableBooks : availableBooks]
}
}
def addBook = {
def author = Author.get( params.id )
def book = Book.get(params.bookId)
author.addBook(book)
author.save()
redirect(action:'edit', params:[id:author.id])
}
def removeBook = {
def author = Author.get( params.id )
def book = Book.get(params.bookId)
author.books.remove(book)
author.save()
redirect(action:'edit', params:[id:author.id])
}
...
}
%PROJECT_HOME%\grails-app\controllers\BookController.groovy
class BookController {
...
def delete = {
def book = Book.get( params.id )
if (book) {
def authors = book.authors
// Removing the book from its authors' list
authors.each { author ->
println (">>>>>>>>>>>> removing book:" + book.title + " from author: " +
author.name)
author.books.remove(book)
author.save()
}
book.delete()
flash.message = "Book ${params.id} deleted."
redirect(action:list)
}
else {
flash.message = "Book not found with id ${params.id}"
redirect(action:list)
}
}
def edit = {
println (">>>>>>>>>>>>> editBook: " + params.id)
def book = Book.get( params.id )
if(!book) {
flash.message = "Book not found with id ${params.id}"
def addAuthor = {
def bookId = params.id
def book = Book.get(bookId)
def author = Author.get(params.authorId)
println (">>>>>>>>>>>>> addAuthor: " + params['authorId'] + ' for book: ' + book.title)
// if the book is updated from here, all the other books for this author are removed
// book.addAuthor(author) // deletes the existing books for this author and adds this
book
// book.authors.add(author) // Doesn't work at all, no change to authors
/* if (!book.save())
{
book.errors.each {
println '>>>>>>>>>>>>>>>>>>>> Error saving book' + it
}
}
*/
// MUST DO this because inverse='true' in hbm.xml
author.addBook(book)
author.save()
redirect(action:'edit',id:bookId)
}
def removeAuthor = {
def bookId = params.id
def book = Book.get(bookId)
def author = Author.get(params.authorId)
println (">>>>>>>>>>>>> START removeAuthor: " + bookId + ' for author: ' + author.name)
author.books.remove(book)
println (">>>>>>>>>>>>> DONE removeAuthor: " + params.bookId + ' for author: ' +
author.name)
author.save()
redirect(action:'edit',id:bookId)
}
...
}
%PROJECT_HOME%\grails-app\views\author\edit.gsp
%PROJECT_HOME%\grails-app\views\book\edit.gsp
AuthorBook.zip
Introduction
Often a web application needs to impose restrictions on which HTTP request methods are allowed for
specific actions in the application. For example, initiating any action that destroys or modifies data using
an HTTP-GET is generally considered to be a bad idea.
The request method may be inspected inside of a controller action and the application may respond
however is appropriate. The code below is a way to prevent the delete action from being invoked using
an HTTP-GET.
class PersonController {
def delete = {
if(request.method == 'GET') {
// redirect to the list action
redirect(action:list)
} else {
// the rest of the delete action goes here
}
}
}
Instead of redirecting to some other action the application may want to return a 403 (Forbidden Access)
error code like this:
class PersonController {
def delete = {
if(request.method == 'GET') {
response.sendError(403)
} else {
// the rest of the delete action goes here
}
}
}
A problem with inspecting the request method inside of the controller action is that this code ends up
being repeated in a lot of actions within a controller, in many controllers in an application and in many
applications. For specialized application specific handling of invalid requests this may make sense but for
the general case the Grails framework provides a simple declarative syntax to help with this problem.
As of version 0.3 Grails provides a simple declarative syntax to help limit access to controller actions
based on the HTTP request method. The optional allowedMethods property may be added to a controller
to let the framework know which HTTP methods are allowed for controller actions. By default, all request
methods are allowed for all controller actions. The allowedMethods property only needs to be defined if
the controller contains actions that need to be restricted to certain request methods.
The allowedMethods property should be assigned a value that is a Map. The keys in the map should be
the names of actions that need to be restricted. The value associated with each of those keys may be
either a String or a List of Strings. If the value is a String, that String represents the only request
method that may be used to invoke that action. If the value is a List of Strings the List represents all of
the request methods that may be used to invoke that action. If the specified restrictions are violated
then a 403 will be returned in the response.
Example:
class PersonController {
IDE Integration
Eclipse Integration
Grails automatically creates Eclipse project and classpath files for you, so to import a Grails project just
right-click in the "Package Explorer" and select "Import" then "Existing project into Workspace" and
"Browse" to the location of your project.
Then immediately click "Ok" followed by "Finish" and your project will be set-up.
There is a known issue that Grails will not run properly if you try to use the root directory of your
drive as your project, or paths with spaces.
You will need to create an Eclipse classpath variable called GRAILS_HOME that points to the location
where you installed Grails for the project to build successfullly by going to Windows -> Preferences... ->
Java -> Build path -> Classpath Variables -> New.
If you don't already have GRAILS_HOME as part of your standard environment, in order to run your
Grails project, you will need to establish that value in the Run dialog (Run...) under the Environment tab,
to the same value as above.
Also, if you are using JSP you will need to add your JDK's tools.jar library to your project classpath
otherwise jetty will display compilation errors. See this page for info:
http://nuin.blogspot.com/2005/05/launch-jetty-from-eclipse-solving.html
If you are using the Eclipse Groovy plugin then make sure you disable the preference 'Groovy
Compiler Generating Class Files' (Eclipse -> Window -> Preferences -> Groovy Preferences)
before importing the Grails project. By default this option is enabled and generates class files for
your groovy files, and stores them in the basedir of your Grails project. When these class files are
generated, unexpected behaviour is encountered like not able to generate controllers and views
for you domain classes.
Grails also automatically creates an Eclipse run configuration for you. To run the project you are in use
the "Run" dropdown to open the "Run" dialog then under "Java Applications" find the name of your
project select it and click "Run". The Grails application will load embedded inside Eclipse, any changes
made inside the Eclipse project can be auto-reloaded.
org.mortbay.util.MultiException[java.io.FileNotFoundException: {yourpath}/web-app]
at org.mortbay.http.HttpServer.doStart(HttpServer.java:731)
at org.mortbay.util.Container.start(Container.java:72)
at grails.util.GrailsMain.main(GrailsMain.java:67)
which will package up grails into the web-app directory in the same way as the "grails run-app" command
will. This is then used as the base for eclipse to execute.
You can step debug a Grails application if you install the latest build of the Groovy Eclipse plug-in. What
you need to do is the following:
• Open up the Groovy file you want to debug (lets say a controller called BookController.groovy)
then set a break point on the line you want to stop at.
• Now debug the application in the same way as you did in the above section on "Running a Grails
application" except with the "Debug" menu.
• Load your browser and navigate to the action that calls the code.
Eclipse should then stop at the appropriate place and you can then inspect variables and step through the
code. If you have the Grails source code set-up on your Source path you can step into that code too.
You can configure grails as an "External Tool", allowing you to create domain classes etc. from within
Eclipse:
The gsp files are just jsp files with a special taglib. The extension gsp has to be added as follows:
• General -> Editors -> File Associations: add *.gsp and link the JSP Editor to it.
• General -> Content Types Fold out Text -> JSP and add *.gsp
This enables jsp editing for the gsp files. To use the taglib add the following at the start of the gsp:
Troubleshooting
1. If you getting the following error every time you save *.groovy file in your project:
•Right click on package explorer's project name and open "Properties..." dialog.
•Select "Builders" and make sure that "Groovy Builder" is checked.
•Select "Java Compiler/Building" and check "Enable project specific settings".
•Append "*.groovy" to "Filtered Resources" text field, to prevent ".groovy" files being
copied to the output directory. Note that the path separator is "," not ";"
• Apply changes and close dialog.
• Clean your project. Make sure that the output directory doesn't contain "*.groovy" files
2. If Eclipse complains that it can not find the sources where breakpoints are set ensure the following:
• Step filtering is enabled for groovy.*, org.codehaus.* (more about this
http://groovy.codehaus.org/Debugging+with+Eclipse )
• Build out put for the project is in a separate folder (say /bin ). Make sure this is present for
Project->Properties->Groovy Project Properties
3. Few other recommendations:
• Make sure to add all the libraries from grails-app/lib folder to the project
• Using verbose logging/tracing through log4j.properties until everything works from the Eclipse
IDE. Sometimes if some library is not found, unless it is printed in the console, it is difficult to
find out what went wrong.
• Make sure to use the same JDK for tools.jar as well as the runtime jar rt.jar. Do note
sometimes using the JRE instead of rt.jar causes problems.
• Sometimes "launch configuration" generated by grails is not in sync with the way ant's
If running from IDE has issues, most likely it is because some library is missing. Ensure that all libraries
under GRAILS_HOME/dist, GRAILS_HOME/ant/lib, GRAILS_HOME/lib and your project folder/lib are
added to the build path of the project.
Prerequisites
• An installation of Java SDK 1.4 or higher and have set your JAVA_HOME variable to the SDK install
location
Steps
Prerequisites
In order to start using Grails from SVN you need to have the following:
• An installation of Java 1.4 or higher and have set your JAVA_HOME variable to the install location
• A working installation of Apache Ant 1.6.5 or higher
• JUnit (to run the build tests - put junit.jar in your ANT_HOME\lib directory)
• An installation of Subversion
Steps
Introduction
Welcome to the Grails documentation, this documentation is as up-to-date as possible, but if you find any
inconsistency or gaps in the documentation please don't hesitate to report it to the Mailing Lists or update
it yourself via the Wiki.
The Background
The rise of Ruby on Rails has signified a huge shift in how we build web applications today, it is a
fantastic framework with a growing community. There is, however, space for another such framework
that integrates seamlessly with Java. Thousands of companies have invested in Java and these same
companies are losing out on the benefits of a Rails-like framework. Enter Grails.
Grails is not just a Rails clone, it aims to provide a Rails-like environment that is more familiar to Java
developers and that uses idioms that Java developers are more familiar with making the adjustment in
mentality to a dynamic framework less of a jump. The concepts within Grails like interceptors, tag libs,
Groovy Server Pages (GSP) make those in the Java community feel right at home.
Grails' foundation on solid Open Source technologies such as Spring, Hibernate and SiteMesh give it even
more potential in the Java space with Spring providing powerful inversion of control and MVC, Hibernate -
stable and mature object relational mapping technology with the ability to integrate with legacy systems
and SiteMesh - flexible layout control and page decoration.
Grails complements these with additional features taking advantage of the coding by convention
paradigm such as:
Scheduling Jobs
Overview
Grails allows you to schedule jobs to be executed using a specified interval or cron expression. The
underlying system uses the Quartz Enterprise Job Scheduler configured via Spring, but is made simpler
by the coding by convention paradigm.
Scheduling Jobs
To create a new job run the "grails create-job" command and enter the name of the job. Grails will create
a new job and place it in the "grails-app/jobs" directory:
class MyJob {
def startDelay = 60000
def timeout = 1000
def execute(){
print "Job run!"
}
}
The above example will wait for 1 minute and after that will call the 'execute' method every second. The
'timeout' and 'startDelay' properties are specified in milliseconds and must have Integer or Long type. If
these properties are not specified default values are applied (1 minute for 'timeout' property and 30
seconds for 'startDelay' property). It isn't recommended to set 'startDelay' property value lesser than 30
seconds since your application needs to fully startup before executing jobs. Jobs can optionally be placed
in different groups.
Important: in earlier versions of Grails (before 0.5) 'startDelay' and 'timeout' properties must be defined
as Strings and default values are 1 minute for 'timeout' and 0 seconds for 'startDelay'
Jobs can be scheduled using a cron expression. For those unfamiliar with "cron", this means being able to
create a firing schedule such as: "At 8:00am every Monday through Friday" or "At 1:30am every last
Friday of the month". (See the API docs for the CronTrigger class in Quartz for more info on cron
expressions):
class MyJob {
def cronExpression = "0 0 6 * * ?"
def execute(){
print "Job run!"
}
}
Jobs are configured for auto-wiring by name thus properties can be injected into them. To get hold of the
data source you can do:
Or a service class:
The Grails application context is configured using convention so most types can be injected simply by
using their property name representation (ie the first letter being lower case in the majority of cases).
(Since 0.5) Jobs are configured by default to have Hibernate Session bounded to thread each time job is
executed. This is required if you are using Hibernate code which requires open session (such as lazy
loading of collections) or working with domain objects with unique persistent constraint (it uses Hibernate
Session behind the scene). If you want to override this behavior (rarely useful) you can use
'sessionRequired' property:
Configuring Logging
Grails uses Apache Commons Logging, defaulting to Log4J for the log output and configuration.
All application artefacts have a dynamically added "log" property. This includes Domain classes,
Controllers, Taglibs, Jobs, Services, Bootstraps, Datasources etc.
The artefact type IDs come from the registered artefact handlers. At the time of writing, out of the box
these are:
• bootstrap
• dataSource
• tagLib
• service
• controller
• task
• domain
Within controllers you can use the "log" property supplied by Grails to log using standard commons
logging methods. You can configure the logging of each controller individually by editing log4j.properties
as follows:
log4j.logger.YourController=debug, stdout
log4j.additivity.YourController=false
To log all SQL queries and all the stuff hibernate does, add the line
log4j.logger.org.hibernate=debug, stdout
web-app/WEB-INF
Scaffolding
What is Scaffolding?
Scaffolding allows you to auto-generate a whole application for a given domain class including:
Enabling Scaffolding
The simplest way to get started with scaffolding is to enable scaffolding via the "scaffold" property. For
the "Book" domain class, you need to set the "scaffold" property on a controller to true:
class BookController {
def scaffold = true
}
The above works because the "BookController" follows the same naming convention as the "Book"
domain class, if we wanted to scaffold a specific domain class you can reference the class directly in the
scaffold property:
And thats it! If you run this grails application the necessary actions and views will be auto-generated at
runtime. The following actions are dynamically implemented by default by the runtime scaffolding
mechanism:
• list
• show
• edit
• delete
• create
• save
• update
An interface like the one demonstrated in the screenshots below will be generated automatically:
Dynamic Scaffolding
Because Grails does not use code templates to achieve this you can add your own actions to the
scaffolded controller that interact with the scaffolded actions. For example, in the below example,
changeAuthor redirects to the show action:
class BookController {
def scaffold = Book.class
def changeAuthor = {
def b = Book.get( params["id"] )
b.author = Author.get( params["author.id"] )
b.save()
You can also override the scaffolded actions with your own actions if necessary:
class BookController {
def scaffold = Book.class
The above scaffolding features are useful but in real world situations its likely that you will want to
customize the logic and views. Grails allows you to generate a controller and the views used to create the
above interface via the command line. To generate a controller type:
grails generate-views
grails generate-all
All these commands will prompt you for the name of the domain class to generate to various artifacts for
the specified domain class. You can even generate a controller and views for a domain class that is
written in Java and mapped with Hibernate!
The views that Grails generates have some form of intelligence in that they adapt to the Validation
constraints. For example you can change the order that fields appear in the views simply by re-ordering
the constraints in the builder:
def constraints = {
title()
releaseDate()
}
You can also get the generator to generate lists instead of text inputs if you use the "inList" constraint:
def constraints = {
title()
category(inList:["Fiction", "Non-fiction", "Biography"])
releaseDate()
}
def constraints = {
age(range:18..65)
}
Restricting the length via a constraint also effects how many characters can be entered in the generated
view:
def constraints = {
name(length:0..30)
}
And you can change an input field to be a text area by using the "widget" constraint:
Java Integration
If your domain model is written in Java and mapped with Hibernate you can still take advantage of Grails'
scaffolding mechanism. For the purpose of this documentation it is assumed you have read how Grails'
Hibernate integration works in the section on GORM, needless to say to scaffold a hibernate domain class
simply reference the domain class in the controller:
import com.books.HibernateBook
class BookController {
def scaffold = HibernateBook.class
}
If you want to generate the controller and views for a Hibernate domain class you can still do so, but
make sure you type the full package and class name.
To integrate with the Grails constraints mechanism and hence hook into useful things like the way the
views are generated and Grails' Validation mechanism you can do so by creating a Groovy script following
the naming convention of your domain class and ending in the "Constraints" suffix. For example for the
"HibernateBook" class defined above you would need to create a
"com/books/HibernateBookConstraints.groovy" script in the same package is the class itself. Within the
script just define constraints in the same way as you would do in a GORM class but without the def or
static keywords before the name:
constraints = {
title(length:5..15)
desc(blank:false)
}
Scripting events
As of v0.5 there is now the ability to hook into scripting events. These are events triggered during
execution of Grails target and plugin scripts.
For example, you can hook into status update output (i.e. "Tests passed", "Server running") and the
creation of files or artefacts.
The mechanism is deliberately simple and loosely specified. The list of possible events is not fixed in any
way, so it is possible to hook into events triggered by plugin scripts, for which there is no equivalent
event in the core target scripts.
Event handlers are defined in a script called Events.groovy either in the scripts/ folder of a plugin, or in
your .grails/scripts/ folder in your user home directory. All events scripts are called whenever an event
occurs, so you can have 10 plugins handling events and also a custom per-user script.
Event handlers are closures defined in Events.groovy, with a name beginning with "event". The following
example can be put in your <home>/.grails/home and will use the Mac OS X "Growl" application to pop
up notifications of script status (you need to install the growlnotify extras from the Growl's .dmg):
You can see here the three handlers eventCreatedArtefact, eventStatusUpdate, eventStatusFinal.
Currently Grails scripting will generate the following events:
Not all the scripts have been updated in SVN head so not all of these occur, and some only occur
Triggering events
If you are writing a custom script for a plugin you should ensure that you follow existing conventions for
event generation, and add any new useful events relating to your plugin.
To trigger an event simply include the Init.groovy script and call the event() closure:
Ant.property(environment:"env")
grailsHome = Ant.antProject.properties."env.GRAILS_HOME"
...
The following is raw text and requires further editing and adding to....
Making it simple to build a secure webapp out-of-the-box is one of the key criteria for adoption of the
Grails platform......although i'd have trouble telling you the exact definition of 'secure' other than it's
enough so that a Developer/Architect could allay any questions/fears from Management.
Grails is no more or less secure than Java Servlets. We can add more to reduce the risk of mistakes, but
ultimately the core problem is developer awareness.
SQL injection
Hibernate automatically escapes data when committing to database, but avoid writing bad dynamic HQL
code that uses unchecked request params
Phishing
HTML/URL injection
HTML/URL injection is easily handled with the codecs introduced in Grails 0.4, and the taglib fixes to use
encodeAsURL where appropriate.
Services
Grails Services
A service is a class that holds one or more methods that implement business logic. Logical parts of the
business logic are contained in separate service classes. Services are demarcated by transactions to
make units of work atomic on the persistence level. When certain types of exceptions are thrown
transactions are rolled back.
Services need to be registered with the middle tier and also need transactional configuration next to the
configuration of optional AOP services.
Services are application-scoped, which means it is not a good idea to use instance variables because they
can and will be modified concurrently (at the same time).
Service class names should start with the name of the service and end with "Service". A country service
would thus be called "CountryService".
By default transaction demarcation is enabled for all services, meaning that by default all methods of a
service are wrapped in a transaction. Transaction demarcation can be disabled for specific services by
creating a "transactional" property and setting is to false:
class CountryService {
boolean transactional = false
}
Access to service methods is not synchronised, so nothing prevents concurrent execution of those
functions.
In fact, because the service is a singleton and may be used concurrently, you should be very careful
about storing state in a service. Or take the easy (and better) road and never store state in a service.
Dependency Injection
Other services can be injected into a service by creating corresponding properties. To inject the
CountryService create a "countryService" property.
CountryService countryService
javax.sql.DataSource dataSource
This could be used in conjunction with Spring's JdbcTemplate to perform direct transactional SQL
operations or with Groovy Sql
Accessing Services
From a controller
In a typical multitier scenario you can easily access services using dependency injection, for example
from a controller:
class CountryService {
def String sayHello(String name) {
return "hello ${name}"
}
}
class GreetingController {
CountryService countryService
def helloAction = {
render(countryService.sayHello(params.name))
}
}
From a servlet
Alternatively, you can access services from other places of your web application (like servlets) if you need
it. Service objects are beans which can be retrieved from the Spring Bean Factory. You can proceed this
way:
Implement a java interface containing the service method definitions which you want to be available, for
example:
package serviceinterfaces;
Modify the CountryService groovy class for implementing the CountryServiceInt interface:
Spring Integration
Beans can be configured to auto-wiring into Grails components by adding entries into the
"%PROJECT_HOME%\spring\resources.xml" file of your Grails application. Controllers by default use
auto-wiring by name so a bean defined as follows
class SomeController {
def myBean
//.....
}
class SomeService {
MyBean myBean
def serviceMethod() {
myBean.invoke()
}
}
Also JNDI DataSources can be set up with a bean id "dataSource". More details under Configuration page.
This page forms a guide to developers wishing to develop plugins for Grails. Since 0.4, Grails provides a
number of extension points that allow you to extend anything from the command line interface to the
runtime configuration engine. The following sections detail how to go about it:
Often it is valuable to monitor resources for changes and then reload those changes when they occur.
This is how Grails implements advanced reloading of application state at runtime. For example, consider
the below simplified snippet from the ServicesPlugin that Grails comes with:
class ServicesGrailsPlugin {
...
def watchedResources = "file:./grails-app/services/*Service.groovy"
...
def onChange = { event ->
if(event.source) {
def serviceClass = application.addServiceClass(event.source)
def serviceName = "${serviceClass.propertyName}"
def beans = beans {
"$serviceName"(serviceClass.getClazz()) { bean ->
bean.autowire = true
}
if(event.ctx) {
event.ctx.registerBeanDefinition(serviceName,
beans.getBeanDefinition(serviceName))
}
}
}
}
Firstly it defines a set of watchedResources as either a String or a List of strings that contain either the
references or patterns of the resources to watch. If the watched resources is a Groovy file, when it is
changed it will automatically be reloaded and passed into the onChange closure inside the event object.
• event.source - The source of the event which is either the reloaded class or a Spring Resource
• event.ctx - The Spring ApplicationContext instance
• event.plugin - The plugin object that manages the resource (Usually this)
• event.application - The GrailsApplication instance
From these objects you can evaluate the conventions and then apply the appropriate changes to the
ApplicationContext and so forth based on the conventions, etc. In the "Services" example above, a new
services bean is re-registered with the ApplicationContext when one of the service classes changes.
As well as being able to react to changes that occur when a plugin changes, sometimes one plugin needs
to "influence" another plugin.
To get round this, you can specify which plugins another plugin "influences". What this means is that
when one plugin detects a change, it will reload itself and then reload all influenced plugins. See this
snippet from the ServicesGrailsPlugin:
If there is a particular plugin that you would like to observe for changes but not necessary watch the
resources that it monitors you can use the "observe" property:
In this case when a Hibernate domain class is changed you will also receive the event chained from the
hibernate plugin
Contribute a Plugin
As of Grails 0.4, Grails provides an extensible plugin architecture for developing plugins that extend
Grails' capabilities in whatever way you choose. Checkout The Plug-in Developers Guide for more info on
how to develop plugins.
If you decide to make the jump and develop a plugin Codehaus provides a number of services to Grails
plugin developers including:
Also Grails plugins hosted at Codehaus can be installed with the command:
This feature (the plugin repository) is not yet functioning, coming soon for 0.5
And retrieved with the grails list-plugins target. Every time a release of a Grails is made the plugins
hosted at Codehaus will be built and placed within http://dist.codehaus.org/grails-plugins
Please post your ideas on the Mailing lists if you are interested in developing a plugin
Creating a Plugin
This will create a plugin project for the name you specify. Say for example grails create-plugin
example would create a new plugin project called example. The structure of a Grails plugin is exactly the
same as a regular Grails project's directory structure, except that in the root of the plugin directory you
will find a plugin Groovy file. Following our example plugin it will look something like:
class ExampleGrailsPlugin {
def version = 0.1
...
}
All plugins must have this class in the root of their directory structure to be valid. The plugin class defines
the version of the plugin and optionally various hooks into plugin extension points (covered shortly).
In fact, not only is the structure the same, but a plugin is a Grails application so you can just type
grails run-app from the root of the plugin directory to execute a Grails plugin as a Grails app.
To distribute the example plugin you need to navigate to its root directory using cd example and then
type:
grails package-plugin
This will create a zip file of the plugin starting with "grails" then the plugin name and version. For
example in the above case this would be grails-example-0.1.zip.
Once you have a plugin distribution file you can navigate to a Grails project and type:
If the plugin was hosted on a remote HTTP server you can also do:
Also for Grails plugins that are distributed at http://dist.codehaus.org/grails/plugins you can do:
Plugin Basics
A plugin can add a new script simply by providing the relevant Gant script within the scripts directory of
the plugin:
+ MyPlugin.groovy
+ scripts <-- additional scripts here
+ grails-app
+ controllers
+ services
+ etc.
+ lib
A plugin can add a new controller, taglib, service etc. by simply creating the relevant file within the
grails-app tree. Note that when the plugin is installed it will be loaded from where it is installed and not
copied into the main dir tree.
+ ExamplePlugin.groovy
+ scripts
+ grails-app
+ controllers <-- additional controllers here
+ services <-- additional services here
+ etc. <-- additional XXX here
+ lib
Plugin Dependencies
Plugins often depend on the presence of other plugins and can also adapt depending on the presence of
others. To cover this, a plugin can define two properties. The first is called dependsOn. For example, take
a look at this snippet from the Grails Hibernate plugin:
class HibernateGrailsPlugin {
As the above example demonstrates the Hibernate plugin is dependent on the presence of 4 plugins: The
dataSource plugin (DataSourceGrailsPlugin), The domainClass plugin (DomainClassGrailsPlugin), the i18n
plugin and the core plugin.
Essentially the dependencies will be loaded first and then the Hibernate plugin. If all dependencies do not
load, then the plugin will not load.
However, this is a "hard" dependency in that if the dependency is not resolved, the plugin will give up
and won't load. It is possible though to have a "weaker" dependency using the loadAfter property:
Here the plugin will be loaded after the "controllers" plugin if it exists, otherwise it will just be loaded. The
plugin can then adapt to the presence of the other plugin, for example the Hibernate plugin has this code
in the doWithSpring closure:
if(manager?.hasGrailsPlugin("controllers")) {
openSessionInViewInterceptor(OpenSessionInViewInterceptor) {
flushMode = HibernateAccessor.FLUSH_AUTO
sessionFactory = sessionFactory
}
grailsUrlHandlerMapping.interceptors << openSessionInViewInterceptor
}
Here the Hibernate plugin will only register an OpenSessionInViewInterceptor if the "controllers" plugin
has been loaded.
The previous snippet presented an example of how to interact with the PluginManager. The manager
variable is an instance of the GrailsPluginManager interface and it provides methods to interact with other
plugins and the PluginManager itself from any plugin.
The Basics
Grails plugins allow you to register dynamic methods with any Grails managed or other class at runtime.
New methods can only be added within a doWithDynamicMethods closure of a plugin. After which no new
methods can be added. This is to ensure thread safety when using dynamic methods.
For Grails managed classes like controllers, tag libraries and so forth you can add methods, constructors
etc. using the ExpandoMetaClass mechanism by accessing each controller's MetaClass:
class MyPlugin {
For other classes you can use the special "metaClass" property of each java.lang.Class. :
To do this your plugin MUST depend on the core Grails plugin: static dependsOn = [core:0.4]
as this plugin sets up the "metaClass" property on java.lang.Class
class MyPlugin {
The doWithDynamicMethods closure gets passed the Spring ApplicationContext instance. This is useful as
it allows you to interact with objects within it. For example if you where implementing a method to
interact with Hibernate you could use the SessionFactory instance in combination with a
To use the Hibernate plugin your plugin MUST depend on the hibernate Grails plugin: static
dependsOn = [hibernate:0.4] as this plugin sets up the SessionFactory and Hibernate
dependencies
import org.springframework.orm.hibernate3.HibernateTemplate
class MyHibernatePlugin {
metaClass.myNewPersistentMethod = { ->
def sf = applicationContext.sessionFactory
def ht = new HibernateTemplate(sf)
Also because of the autowiring and dependency injection capability of the Spring container you can
implement more powerful dynamic constructors that use the application context to wire dependencies
into your object at runtime:
class MyConstructorPlugin {
domainClass.metaClass.ctor = {->
return applicationContext.getBean(domainClass.name)
}
}
}
}
Grails contains a special MetaClass called an ExpandoMetaClass that allows you to dynamically add
methods, constructors, properties and static methods using a neat closure syntax. ExpandoMetaClass
also has an even more dynamic cousin: DynamicMethodsExpandoMetaClass
At a basic level the ExpandoMetaClass can be created simply by passing in the desired class:
However, this will not place the ExpandoMetaClass in the registry and hence is only useful for
per-instance MetaClasses. If you want the ExpandoMetaClass to be shared and available VM wide you
need to do:
The second boolean argument indicates to the ExpandoMetaClass that it should be placed in the registry.
The final thing you need to know about creating ExpandoMetaClass is that it cannot be used until you call
initialize() and once you call initialize() you cannot add new methods. This is to ensure thread safety. So
the basic usage pattern is as follows:
metaClass.initialize()
class Book {
String title
}
Note that in this case the left shift << operator is used to "append" the new method. If the method
Static methods can also be added using the same technique as above with the addition of the "static"
qualifier:
Adding constructors
Adding constructors is again similar except that you use a special "ctor" property of the MetaClass:
Adding properties
Properties can be added in a couple of ways. Firstly you can use the instance method syntax seen
previously:
In this case the property is dictated by the closure and is a read-only property. You can add the
equivalent setter but then remember you will have to store the property somewhere for retrieval later so
make sure you use thread safe code.
In this case the property is mutable and has both a setter and getter.
However, using this technique the property is stored in a ThreadLocal, SoftReference Map so don't
expect the value to stick around forever!
With ExpandoMetaClass you can also use Groovy's method pointer syntax to borrow methods from other
classes. For example:
class AnotherClass {
def borrowMe() {
"hello!"
}
}
metaClass.borrowed = another.&borrowMe
Grails' DynamicMethodsExpandoMetaClass
As well as the regular ExpandoMetaClass Grails has another powerful MetaClass called
DynamicMethodsExpandoMetaClass. This MetaClass allows you to match a number of methods using a
regex pattern.
Creating an instance
import org.codehaus.groovy.grails.commons.metaclass.*
The above code will create the MetaClass, but not place it in the MetaClassRegistry, which is useful if you
want to do per-instance MetaClass'. To place a DynamicMethodsExpandoMetaClass in the registry you
need to do:
import org.codehaus.groovy.grails.commons.metaclass.*
To match instance methods you basically have to assign a closure to a property that is a regex starting
with ^ and ending with $:
The above example will match all methods that start with "findBy" (such as findByTitle, findbyFoo etc.).
The first argument passed to the closure is a java.util.regex.Matcher the second argument is the
arguments to the method. From there you can do what you like within the body of the closure. To get a
reference to "this" you should use the "delegate" property
Like ExpandoMetaClass this MetaClass can also do static methods by using a "static" qualifier:
Once you've constructed your MetaClass (in this example we're doing it for the Book class) you can then
happily invoke the added methods on it:
There are a number of other properties you can specific on a plugin class and in the next few sections we
look at how you can use those.
class ExampleGrailsPlugin {
def version = 0.1
...
}
First, you can hook in Grails runtime configuration by providing a closure property called doWithSpring.
For example the following snippet is from one of the core Grails plugins that provides i18n support:
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
class I18nGrailsPlugin {
def doWithSpring = {
messageSource(ReloadableResourceBundleMessageSource) {
basename = "WEB-INF/grails-app/i18n/messages"
}
localeChangeInterceptor(LocaleChangeInterceptor) {
paramName = "lang"
}
localeResolver(CookieLocaleResolver)
}
}
This plugin sets up the Grails messageSource bean and a couple of other beans to manage Locale
resolution and switching. It using the Spring Bean Builder syntax to do so.
Grails generates the WEB-INF/web.xml file at load time, and although plugins cannot change this file
directly, they can participate in the generation of the file. Essentially a plugin can provide a
doWithWebDescriptor closure that gets passed the web.xml as a XmlSlurper GPathResult.
plugin.watchedResources.each {
def match = it.filename =~ /(\w+)(Controller.groovy$)/
if(match) {
def controllerName = match[0][1]
controllerName = GCU.getPropertyName(controllerName)
controllers << controllerName
}
}
def mappingElement = webXml.'servlet-mapping'
controllers.each { c ->
mappingElement + {
'servlet-mapping' {
'servlet-name'("grails")
'url-pattern'("/${c}/*")
}
}
}
...
}
Here the plugin goes through all its watched resources, finding all the controller names and then creates
<servlet-mapping> elements appended after the last <servlet-mapping> element found in the web.xml
Note that at the point of web.xml generation there is no GrailsApplication instance, so you need to
use the conventions in the file names instead.
Sometimes it is useful to be able do some runtime configuration after the Spring ApplicationContext has
been built. For this you can define a doWithApplicationContext closure property.
class SimplePlugin {
def name="simple"
def version = 1.1
So as mentioned previously, a plugin is merely a regular Grails application with this special file; however
when installed, the structure of a plugin differs slightly. For example, take a look at this plugin directory
structure:
+ grails-app
+ controllers
+ domain
+ taglib
etc.
+ lib
+ src
+ java
+ groovy
+ web-app
+ js
+ css
Basically when a plugin is installed into a project, the stuff within the grails-app directory will go into a
directory like $PROJECT_HOME/plugins/example-1.0/grails-app. They will NOT be copied into the main
source tree. A plugin NEVER messes with a project's primary source tree.
However, static resources such as those inside the web-app directory will be copied into the project's
web-app directory under a special "plugins" directory for example web-app/plugins/example-1.0/js. It
is therefore the responsibility of the plugin to make sure that it references static resources from the
correct place. For example if you were referencing a JavaScript source from a GSP this would be:
To make this easier there is a special pluginContextPath variable available that changes whether you're
executing the plugin standalone or whether you've installed it into an application:
At runtime this will either evaluate to /js or /plugins/example/js depending on whether the plugin is
running standalone or has been installed in an application
Java & Groovy code that the plugin provides within the lib and src/java and src/groovy directories will
be compiled into the main project's web-app/WEB-INF/classes directory so that they are made available
at runtime.
Unit testing
To create a test suite run the "grails create-test-suite" target or just create a new class in
"%PROJECT_HOME%\grails-test" that extends GroovyTestCase and ends with "Tests".
Below is an example of a test suite that tests the validate method on a domain class:
def testValid() {
def b = new Book(title:"Groovy in Action", author:"Dierk Koenig")
assert b.validate()
}
}
For more info on how to write unit tests using Groovy see the section on Unit Testing on the main
Groovy website. This page contains a useful list of all the different assert methods that come with
the JUnit and GroovyTestCase superclasses.
You may find that if you are testing your persisted domain model objects and accessing collection
properties that you get hibernate errors. For example, say I'm writing a social bookmarking application
and I have a User model object which relates to many UserBookmark objects. (So my User class defines
a "Set userBookmarks" property.)
I want to unit test business logic in my User class, so I start out with the following test:
/**
* Tests saveBookmark
*/
void testSaveBookmark() {
// verify boris has no bookmarks yet
def user = User.get(3)
assertEquals 0, user.userBookmarks.size()
because I'm accessing a collection property on my user object. (Behind the scenes, Hibernate has created
a placeholder object for the "userBookmarks" property. The idea is that the data is only fetched when
required.)
This works fine in a normal running Grails application because Grails uses the standard "Open Session in
View" pattern and support classes provided by Spring, but fails in the test because the same principle is
not applied.
The solution is to create a Hibernate session before the test starts and close it after the test finishes.
You can use the setUp() and tearDown() methods (which run before and after each test method,
respectively), like so:
import org.hibernate.Session
import org.hibernate.SessionFactory
import org.springframework.orm.hibernate3.SessionFactoryUtils
import org.springframework.orm.hibernate3.SessionHolder
/**
* Tests my User code
*/
class UserTests extends GroovyTestCase {
SessionFactory sessionFactory
void setUp() {
Session session = SessionFactoryUtils.getSession(sessionFactory, true)
TransactionSynchronizationManager.bindResource(sessionFactory, new
SessionHolder(session))
}
/**
* Tests saveBookmark
*/
void testSaveBookmark() {
// verify boris has no bookmarks yet
def user = User.get(3)
assertNotNull user
assertEquals "boris", user.username
assertEquals 0, user.userBookmarks.size()
}
}
It now passes!
SessionFactory sessionFactory
Validation
Grails allows you to apply constraints to a domain class that can then be used to validate a domain class
instance. Constraints are applied using a "constraints" closure which uses the Groovy builder syntax to
configure constraints against each property name, for example:
class User {
Long id
Long version
String login
String password
String email
Date age
static constraints = {
login(length:5..15,blank:false,unique:true)
password(length:5..15,blank:false)
email(email:true,blank:false)
age(min:new Date(),nullable:false)
}
}
Note that as of Grails 0.4 your constraints must be static or an exception will be thrown.
To validate a domain class you can call the "validate()" method on any instance:
if(user.validate()) {
// do something with user
}
else {
user.errors.allErrors.each {
println it
}
}
By default the persistent "save()" method calls validate before executing hence allowing you to write code
like:
if(user.save()) {
return user
}
So your instance doesn't validate, how do you now display an appropriate error message in the view? For
starters you need to redirect to the right action or view with your erroneous bean:
class UserController {
def save = {
def u = new User()
u.properties = params
if(u.save()) {
// do something
}
else {
render(view:'create',model:[user:u])
}
}
}
In this case we use the render method to render the right view, alternatively you could chain the model
back to a "create" action:
chain(action:create,model:[user:u])
The chain method stored the model in flash scope so that it is available in the request even after the
redirect.
So now to the view, you clearly have an instance with errors, to display them we use a special tag called
"hasErrors":
<g:hasErrors bean="${user}>
<g:renderErrors bean="${user}" as="list" />
</g:hasErrors>
This is used in conjunction with the tag "renderErrors" which renders the errors as a list. In GSP because
you can call tags as regular methods calls it also means you can do some neat tricks to highlight the
errors really easily such as:
The above code will add the "errors" CSS class to the property if there are any errors for the field 'login'
now simply add a CSS style:
And you have the erroneous field highlighting when there is a problem.
Of course the default error message that Grails displays is probably not what you were after, so you will
want to change this. The way you do this is by modifying the "grails-app/i18n/messages.properties" file
and adding a message for the particular error code.
For example if we follow the above example the error code may be "user.login.length.tooshort" so we add
an entry:
user.login.length.tooshort=I'm sorry the login you entered wasn't quite long enough, please
make it longer
For a complete list of error codes and how they correspond to validation constraints see the Validation
Reference
To integrate with the Grails constraints mechanism and hence hook into useful things like the way the
views are generated and Grails' Validation mechanism you can do so by creating a Groovy script following
the naming convention of your domain class and ending in the "Constraints" suffix. For example for a
"com.books.HibernateBook" class (either an EJB3 entity of mapped with Hibernate XML) defined above
you would need to create a "com/books/HibernateBookConstraints.groovy" script in the same package as
the class itself, in the src/java directory tree. Within the script just define constraints in the same way as
you would do in a GORM class but without the @Property notation:
constraints = {
title(length:5..15)
desc(blank:false)
}
Grails supports the creation of views using either JavaServer Pages (JSP) or Groovy Server Pages (GSP).
This section describes how to provide a model to views. For a more complete reference on see the GSP
and JSP references.
Syntactically GSP and JSP are very similar the main difference being that code within scriptlets is in
Groovy not Java! Grails controllers uses a convention mechanism to delegate to an appropriate view. For
example an action called list will delegate to a "list" view:
class BookController {
def list = {
["books" : Book.list() ]
}
}
The corresponding view for the above action would need to be placed in the "grails-app/views/book"
directory with the name "list.jsp" or "list.gsp". The example below is in GSP:
<html>
<head>
<title>Book list</title>
</head>
<body>
<h1>Book list</h1>
<table>
<tr>
<th>Title</th>
<th>Author</th>
</tr>
<g:each in="${books}">
<tr>
<td>${it.title}</td>
<td>${it.author}</td>
</tr>
</g:each>
</table>
</body>
</html>
Defining Layouts
Layouts can be created through Grails's support for SiteMesh. There are 2 ways to create layouts the first
is to associate a view with a layout at the "layout" meta tag to your page:
Now create a layout in called "main.gsp" in the "grails-app/views/layouts" directory and you're done!:
<html>
<head>
<title><g:layoutTitle default="An example decorator" /></title>
<g:layoutHead />
</head>
<body onload="${pageProperty(name:'body.onload')}">
<div class="menu"><!--my common menu goes here--></menu>
<div class="body">
<g:layoutBody />
</div>
</div>
</body>
</html>
The layout uses GSP tags to apply the layout onto the target page.
Layout by Convention
The second way to associated layouts is to use "layout by convention". For example if you have a
controller such as the below:
class BookController {
def list = { ... }
}
You can create a layout called grails-app/views/layouts/book.gsp which will be applied to all views
that the BookController delegates to.
Alternatively you can create a layout called grails-app/views/layouts/book/list.gsp which will only
be applied to the list action within the BookController.
If you have both the above mentioned layouts in place the layout specific to the action will take
precedence when the list action is executed.
30 April 2007
The Grails development team has reached another milestone and is pleased to announce the release of
version 0.5 of the Grails web-application development framework.
Grails is a dynamic web-application framework built in Java and Groovy, leveraging best of breed APIs
from the J2EE sphere including Spring, Hibernate and SiteMesh. Grails brings to Java and Groovy
developers the joys of convention-based rapid development while allowing them to leverage their existing
knowledge and capitalize on the proven and performant APIs Java developers have been using for years.
Development has been intense since the release of 0.4.2 at the end of February, tackling over 190 issues
in this period. This release has seen exciting contributions from new team members and users and
significant functionality enhancements.
Thank you to all the team members, patch contributors and users. A lot of hard work has gone into this
release - we hope you enjoy using this latest installment of the Grails adventure.
New Features
Improvements
Detailed examples
You can now create a URL mapping class that uses, for those interested, a dynamic builder/metaclass
mechanism to map the URI space of your application to your controllers and actions in almost any way
you like. You can pull out parts of the URL as variables and even apply constraints to these.
On top of this, grails taglibs that produce links are smart and will reverse map controller/action
combinations to URLs from the mappings, so links generated within your pages are consistent with your
public URL interface defined in your mappings.
Example:
class MyUrlMappings {
static mappings = {
"/product/$id" {
controller = "product"
action = "show
}
"/$id/$year/$month/$day" {
controller = "blog"
action = "show"
constraints {
year(matches:/\d{4}/)
month(matches:/\d{2}/)
day(matches:/\d{2}/)
}
}
}
}
This removes the necessity to use something like Apache's mod_rewrite to produce user-friendly URLs or
to abstract your URL space away from your implementation.
Documentation
Grails has always had domain class constraints, but often a form or request parameters do not relate
Example:
class LoginController {
def login = { LoginCommand cmd ->
if(cmd.hasErrors()) {
redirect(action:'loginForm')
}
else {
// do something else
}
}
}
class LoginCommand {
String username
String password
static constraints = {
username(blank:false, minSize:6)
password(blank:false, minSize:6)
}
}
Any Groovy class can be used as a command object, with the standard Grails property binding and
validation options. You just specify the typed parameters to the action closure and Grails works out the
rest!
Documentation
GORM has been enhanced to support lists of domain objects in a relationship, as opposed to the default
Set behaviour, providing ordered lists.
Documentation
By default GORM currently uses table-per-hierarchy mapping of classes to the database, which means
that classes in relationships typically are stored in a separate table.
You now can use the Hibernate composition mechanism to embed the data from objects that would
otherwise be considered relationships, within the main table used for the outer class, using the
"embedded" declaration.
class Address {
String street
// ...
String country
}
class Person {
String firstName
String lastName
Address homeAddress
Address workAddress
The "embedded" property is set to the list of property names that represent complex properties that
should be written into the table directly instead of forming a relationship.
Documentation
Base64 codec
Augmenting the existing super-useful codecs supplied in 0.4, we have now added a Base64 codec so that
you can now write code such as this anywhere in your Groovy code or GSPs:
Documentation
We've added support for Ivy dependency resolution for your projects. There are two new targets for this:
grails install-ivy
With the above run once per-project, you can then execute:
grails get-dependencies
The days of accidentally running with the wrong Grails version for your project are gone with 0.5 and
future versions. Applications have metadata stored in a file (not generally for user editing) that includes
the required version of grails, and a version number of your application.
Most of the grails targets therefore refuse to run if the grails version you are using in GRAILS_HOME does
not match that of the project, so that you never omit to run grails upgrade.
Your application's version number is now included in the filename of generated war files. You can set the
version number with "grails set-version"
Furthermore, you can now override the name used for your application so that it does not use the parent
directory name.
A new event mechanism allows target scripts, even those in plugins and your custom application scripts,
to fire and respond to events. By default we have events for artifact and file creation, plugin installation,
Documentation
Version 0.4 added an implicit "log" object for controllers. We have now expanded this feature to all
artefact classes in the application. This means that all domain classes, services, jobs, controllers and so
on (all declared artefacts using the artefact API) receive an implicit log object of their own.
The logs are named in such a way that you can controll the logging of individual artefacts or the category
of artefacts they belong to, or all of your artefacts in the application.
Documentation
The internal artefact mechanisms have been overhauled to allow plugins to register first-class artefacts of
their own that will be managed just like all other grails artefacts, and receive implicit log objects and
other features.
Documentation
Improvements
Along with some of our users, we thought that the implicit addXXXX methods in 0.4 were nice but bit
clunky when you had multiple relationships of the same type. We've sorted this out for 0.5 and are proud
to introduce the minor but important change from addXXXX to addToXXXX methods, where the latter new
form takes the name of the property (collection) not the type of the relationship:
author.removeFromBooks(myBook)
You will also notice we now have the orthogonal removeFromXXXX which manages the bi-directional
references if they exist.
Documentation
Cascading validation
Validation constraints are now applied to all related objects in the object graph when persisting or
validating a domain object.
A new method was added for retrieving multiple objects in one call.
There is now support for positional and named parameters in HQL queries.
We've finally removed the "optionals" property and nullability is purely controlled by the nullable
constraints, and the often duplicated functionality between length and size constraints is being phased
out, with the size variants being the future path.
Taglib optimisations
Specific optimisations related to taglibs should see significant request throughput increases where pages
use many GSP tags.
Improvements to scaffolding
As part of our ongoing effort to increase the real-world usefulness of scaffolding, we have added sortable
columns, improved pagination of large result sets, and other improvements to the default scaffolding
templates.
I18N improvements
Message bundles are reloadable and we have support for more languages out of the box including
Russian, German and Spanish. There have also been changes to some default message codes used, to
make them more logical.
General
One thing to always check in case of unexpected exceptions is the value of the CLASSPATH variable in
your console. Run set CLASSPATH on Windows and echo $CLASSPATH on Mac OS X, Linux and Unix to
print the value. Grails does not depend on the CLASSPATH variable so in case it's set run set
CLASSPATH= on Windows and export CLASSPATH= on Mac OS X, Linux and Unix to remove it.
Q: How do I check my project into SVN / I am getting strange SVN errors with files generated
by Grails
Because Grails (certainly up to an including 0.4) generates and copies some files under the project tree,
SVN and other version control systems can complain about files changing, or files not being in version
control.
For Subversion (SVN) the solution is to mark the correct directories or files to be "ignored". However how
you do this is slightly obscure. See the article Checking Projects into SVN.
Application Servers
JBoss' unified class loader can cause problems with conflicting Jar files. One issue commonly encountered
is with log4j, which is part of both JBoss and Grails. This can be resolved by removing log4j.jar from your
deployed .war file or using scoped classloading (with some caveats).
Ideally you wouldn't want to remove the log4j file from your deployment as this requires some additional
work and will break many automated deployment/testing processes. JBoss' class loaders are based on a
hierarcy of classloaders but this causes issues where there are files shared between the JBoss parent
classloaders and the child classloader for our web application. What we really want to do is tell JBoss to
leave us alone when it comes across files that we have in our .war file. To do this we must 'scope' our
classloader so that the classes we are using are in their own class loader repository away from the JBoss
classes. To do this for a war is relatively straightforward. We must create a file called jboss-service.xml
and place it in our .war file
This will tell the JBoss class loaders to isolate (to a large extent) our classes from those that JBoss is
using, to load our classes first and not to delegate class loading to the parent classloading in case of a
conflict. You need to replace "myappname" with the name of your app or any other string. The only thing
you want is for the loader-repository name to be unique. Generally a good string to use will include your
package name so you can avoid namespace collisions within the webserver
"com.foocompany.webProjectBar:loader=webProjectFooBar.war"
would be a good name this is almost guaranteed to be unique within the container. This is especially
important in a shared hosting environment based on JBoss.
Once you have finished with that file and you drop it into the WEB-INF directory of your web application
and you deploy your web application ideally you should be done. But you're not because of one slight
miscalculation. Log4J will by default look for a log4j.xml file to load its properties from and failing that, it
will fall-back to a log4j.properties. Since we have a classloader hierarchy, you know that if the child
classloader fails - the request to load a class (or resource) gets escalated up the classloader chain until a
classloader accepts it or until they all fail to load the resource at which time an Exception is thrown. The
problem is that the parent classloader already knows about a log4j.xml file - the one loaded by JBoss, so
you will find that you still throw a ClassCastException because log4j.xml for JBoss is trying to load log4j
for your web application. There are two possible fixes for this:
1) In grails we migrate to the log4j.xml file syntax for specifying log4j settings and the problem goes
away because the child classloader will find what its looking for (and this has been suggested and being
evaluated)
2) Change the configuration of the JBoss application server so that it doesn't have a log4j.xml file either.
If you have the ability to make this change, it make save you some headache down the road with
other web applications that bundle log4j in their distributions as well. The fix is very straightforward:
1. Go in the servers conf directory. I have JBoss installed in /jboss-4.0.5.GA, so the conf directory is
/jboss-4.0.5.GA/server/default/conf. If you are deploying into a profile other than default, simply
substitute default for the name of the profile that you are deploying into such as
/jboss-4.0.5.GA/server/foobarprofile/conf.
2. Move the log4j.xml to jboss-log4j.xml
3. Edit the jboss-service.xml file and find the mbean called "org.jboss.logging.Log4JService". Change
the attribute "ConfigurationURL" so that it points to this new jboss-log4j.xml file:
<attribute name="ConfigurationURL">resource:jboss-log4j.xml</attribute>
1. Restart the JBoss application server and now any application that has log4j bundled in it will deploy
properly and with their own log4j configuration.
<mbean code="org.jboss.logging.Log4jService"
name="jboss.system:type=Log4jService,service=Logging"
xmbean-dd="resource:xmdesc/Log4jService-xmbean.xml">
<attribute name="ConfigurationURL">resource:jboss-log4j.xml</attribute>
<!-- Set the org.apache.log4j.helpers.LogLog.setQuiteMode. As of log4j1.2.8
There is a great tutorial on the Oracle website detailing exactly how to setup Grails on Oracle
Q: Deploying on JETTY 6
I had to remove the lib/jsp 2.1 directory from my jetty install to disable JSP 2.1
WebSphere uses the J9 Java Virtual Machine. J9 is also one of the alternatives you'll have to consider on
a PPC Linux box because the Sun JVM doesn't run there. Unfortunately J9 does a lot of work under the
covers to make things run faster that don't work well with Groovy.
Under WebSphere you can set this via the WebSphere Administative Console: Application servers >
server1 > Process Definition > Java Virtual Machine > Generic JVM arguments) save the change and
restart the application server. (See also GRAILS-476.)
We found that sending email caused j9 to throw a GPF Fault - and Tomcat then does it's version of a
Core Dump. Perusing the dump file doesn't seem to help - as there is no indication of the class or
method which caused GPF. GPF is short for General Protection Fault - which means that something is
attempting to access a resource to which they do not have permission (per the underlying operating
system). And finally once past the GPF mail wouldn't send due to some incompatiblity with the Gnu
JavaMail API and the Sun specification JavaMail API. Once the Gnu mail.jar was replaced with the Sun
version - email functioned normally.
Q: Deploying on Websphere
When trying to load a WAR file on WAS 6 and selecting "Parent last" as the classloader option, some
users report the following error:
Workaround: replace the ant.jar with a more recent version of ant (e.g. from GRAILS_HOME/lib).
Solution: replace the Acegi FilterToBeanProxy with the Spring implementation (which uses the Thread
ClassLoader) :
<filter>
<filter-name>filterChainProxy</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
Make sure that you pre-generate the GSP views: 'grails generate-all <Domain>'. This is an issie with
version 0.4.2, which will be fixed for 0.5.
Make sure you are not using JDK1.5 specific features. Use a 1.4 JVM when creating the WAR
file. Make sure you're not using the GrailsAnnotationConfiguration.
Q: I'd like to implement a big project as multi modules with Grails, What to do?
Since version 0.4, Grails has came with a plugin architecture. You can separate your project as a set of
plugins. See how to develop a plug-in here.
View Technologies
A: Sometimes third party javascript libraries depend upon other resources loaded directly from the
javascript files themselves like stylesheets. Examples of libraries that do this would be the Yahoo UI
libraries and niftycube. When the javascript attempts to load the URL Grails changes the URL so that the
resource is not found. Try adding a link using the createLinkTo tag for the particular resource.
Controllers
Q: Can I use the render method to return a binary file to the client?
A: Not at the moment. However the servlet response instance can be used. For example, a zip file is
created on the server and returned to the client:
def createZip = {
byte[] zip = createZipForClient()
response.contentType = "application/octet-stream"
response.outputStream << zip
}
Of course you can! Just use JFreeChart to create an image of the chart you want to show and then
stream that back through the response.
import org.jfree.chart.ChartFactory
import org.jfree.data.general.DefaultPieDataset
import org.jfree.chart.encoders.EncoderUtil
class PiechartController {
def index = {
You will also need to copy jfreechart-1.0.1.jar and jcommon-1.0.0.jar into the libs folder of your grails
app.
In the Author/Book example, Book must implement the Comparable interface, and the set of books must
be of type SortedSet:
class Author {
Long id
Long version
String name
SortedSet books
}
Q: I have a simple domain class that gets erros when trying to view its list?
Be careful with SQL reserved words. The code bellow will result in mapping errors because "order" is an
SQL reserved word. Change that to "sortOrder" or something else.
class Category{
String name
Integer order
Spring will inject the a SessionFactory object into your controller, provided you import the proper libraries
and provide a reference for the injection:
class SomeController {
SessionFactory sessionFactory
def flush_multiple_times = {
assert sessionFactory != null
def hibSession = sessionFactory.getCurrentSession()
assert hibSession != null
hibSession.flush()
// do something
hibSession.flush()
}
}
Security
The most commons way to secure a Grails app is through Controller interceptors and the login tutorial
(PDF). If you want a declarative approach to security another way of securing your applications might be
to use Acegi. This article might give you a solution.
Grails in Eclipse
Your Eclipse is configured to use a Java Runtime Environment or JRE. However, to launch a Grails
application you need a Java Developer Kit or JDK. If you don't have a JDK installed on your system your
can download the latest version from http://java.sun.com
Go to Preference in Eclipse (in the Window menu) and go to "Java/Installed JREs". You will find a JRE
installed, for example "jre1.5.0_09". Now add the JDK by clicking the "Add..." button. Click the
"Browse..." button and select the location of your JDK (for example "C:\Program
Files\Java\jdk1.5.0_09"). Click "Ok" and enter a name for this JDK (for example "JDK 1.5.0_09").
Now make sure to select the JDK you just installed in your launch configuration.
The information in here should be easily adapted to CVS. Replace the svn propset svn:ignore
commands to set the same text in .cvsignore files in the directories specified in the commands.
Up to and including Grails 0.4.x there are files that are generated or copied by Grails within your project
tree. This can be problematic as it is unclear what is to go into SVN and what isn't. In addition, you will
not usually want your compiled .class files going into version control, nor duplicates of your libs etc.
This is correct at the time of writing (Grails 0.4.x) but makes the following assumptions:
Why is this such a hassle? Well SVN prevents files or directories being considered for version control by
checking an "ignores" list that is set via an SVN property. This property is set on specific directories
within your SVN working copy. Therein lies the problem - until you have a working copy you cannot tell it
to ignore files.
This approach is for use when starting a new Grails project - i.e. it does not yet exist on your disk at all,
nor in SVN. It will talk you through your first check in, including the relevant svn:ignore properties, and
avoids any checkin of these ignored files that may or may not exist locally.
With SVN installed, create your project. We will use "MyProject" as the name for the purposes of
demonstration:
Now you must create an empty SVN dirictory under your SVN repository using whatever appropriate tools
you have. This directory should be called the same as MyProject but it doesn't have to be. We will call
this SVN repository directory path "emptysvndir" for this example. Next you do:
That should have your project committed, and changes to ./plugins/core and ./web-app/WEB-INF/ should
be ignored by SVN.
You will not need to check out this project as we have used the "in place import" technique.
At the time of writing (Grails 0.4.x), to checkout this project fresh locally or on another machine
you will need to checkout as usual but then run:
grails upgrade
This approach is for use when you have optimistically imported your entire project into SVN already and
have started getting errors or are being annoyed by the warning messages relating to locally changed
files.
cd MyProject
svn propset svn:ignore "WEB-INF" web-app/
svn propset svn:ignore "core" plugins/
svn rm web-app/WEB-INF
svn rm plugins/core
svn commit -m "Fixing SVN"
That should have your project committed, and changes to ./plugins/core and ./web-app/WEB-INF/ should
be ignored by SVN.
At the time of writing (Grails 0.4.x), to checkout this project fresh locally or on another machine
you will need to checkout as usual but then run:
grails upgrade
Moved here