Beruflich Dokumente
Kultur Dokumente
7. Validation
Grails validation capability is built on Spring's Validator API and data binding capabilities. However
Grails takes this further and provides a unified way to define validation "constraints" with its
constraints mechanism.
Constraints in Grails are a way to declaratively specify validation rules. Most commonly they are
applied to domain classes, however URL Mappings and Command Objects also support constraints.
You then use method calls that match the property name for which the constraint applies in
combination with named parameters to specify constraints:
class User {
...
static constraints = {
login(size:5..15, blank:false, unique:true)
password(size:5..15, blank:false)
email(email:true, blank:false)
age(min:18, nullable:false)
}
}
In this example we've declared that the login property must be between 5 and 15 characters long, it
cannot be blank and must be unique. We've all applied other constraints to the password, email and
age properties.
A complete reference for the available constraints can be found on the reference
1
The Grails Framework - Reference Documentation
guide
The errors property on domain classes is an instance of the Spring Errors interface. The Errors
interface provides methods to navigate the validation errors and also retrieve the original values.
Validation Phases
Within Grails there are essentially 2 phases of validation, the first phase is data binding which occurs
when you bind request parameters onto an instance such as:
def user = new User(params)
At this point you may already have errors in the errors property due to type conversion (such as
converting Strings to Dates). You can check these and obtain the original input value using the
Errors API:
if(user.hasErrors()) {
if(user.errors.hasFieldErrors("login")) {
println user.errors.getFieldError("login").rejectedValue
}
}
The second phase of validation happens when you call validate or save. This is when Grails will
validate the bound values againts the constraints you defined. For example, by default the persistent
save method calls validate before executing hence allowing you to write code like:
if(user.save()) {
return user
2
The Grails Framework - Reference Documentation
}
else {
user.errors.allErrors.each {
println it
}
}
If you need more control you can use hasErrors and eachError:
<g:hasErrors bean="${user}">
<ul>
<g:eachError var="err" bean="${user}">
<li>${err}</li>
</g:eachError>
</ul>
</g:hasErrors>
Highlighting Errors
It is often useful to highlight using a red box or some indicator when a field has been incorrectly input.
This can also be done with the hasErrors by invoking it as a method. For example:
<div class='value ${hasErrors(bean:user,field:'login','errors')}'>
<input type="text" name="login" value="${fieldValue(bean:user,field:'login')}"/>
</div>
What this code does is check if the login field of the user bean has any errors and if it does adds an
errors CSS class to the div thus allowing you to use CSS rules to highlight the div.
3
The Grails Framework - Reference Documentation
This code will look if there is an existing FieldError in the User bean and if there is obtain the
originally input value for the login field.
If the blank constraint was violated Grails will, by convention, look for a message code in the form:
[Class Name].[Property Name].[Constraint Code]
In the case of the blank constraint this would be user.login.blank so you would need a
message such as the following in your grails-app/i18n/messages.properties file:
user.login.blank=Your login name must be specified!
The class name is looked for both with and without a package, with the packaged version taking
precedence. So for example, com.mycompany.myapp.User.login.blank will be used before
user.login.blank. This allows for cases where you domain class encounters message code clashes with
plugins.
For a reference on what codes are for which constraints refer to the reference guide for each constraint.
Displaying Messages
The renderErrors tag will automatically deal with looking up messages for you using the message tag.
However, if you need more control of rendering you will need to do this yourself:
4
The Grails Framework - Reference Documentation
<g:hasErrors bean="${user}">
<ul>
<g:eachError var="err" bean="${user}">
<li><g:message error="${err}" /></li>
</g:eachError>
</ul>
</g:hasErrors>
In this example within the body of the eachError tag we use the message tag in combination with its
error argument to read the message for the given error.
You need to tell the framework which packages to search for @Validateable classes by assigning a list
of Strings to the grails.validateable.packages property in Config.groovy.
// grails-app/conf/Config.groovy
...
grails.validateable.packages = ['com.mycompany.dto', 'com.mycompany.util']
5
The Grails Framework - Reference Documentation
...
The framework will only search those packages (and child packages of those) for classes marked with
@Validateable.