Over a million developers have joined DZone.

Grails Goodness: Custom Data Binding with @DataBinding Annotation

· Java Zone

Learn more about how the Java language, tools and frameworks have been the foundation of countless enterprise systems, brought to you in partnership with Salesforce.

Grails has a data binding mechanism that will convert request parameters to properties of an object of different types. We can customize the default data binding in different ways. One of them is using the @DataBinding annotation. We use a closure as argument for the annotation in which we must return the converted value. We get two arguments, the first is the object the data binding is applied to and the second is the source with all original values of typeSimpleMapDataBindingSource. The source could for example be a map like structure or the parameters of a request object.

In the next example code we have a Product class with a ProductId class. We write a custom data binding to convert the String value with the pattern {code}-{identifier} to a ProductId object:

package mrhaki.grails.binding

import grails.databinding.BindUsing

class Product {

    // Use custom data binding with @BindUsing annotation.
    @BindUsing({ product, source ->

        // Source parameter contains the original values.
        final String productId = source['productId']

        // ID format is like {code}-{identifier},
        // eg. TOYS-067e6162.
        final productIdParts = productId.split('-')

        // Closure must return the actual for 
        // the property.
        new ProductId(
            code: productIdParts[0],
            identifier: productIdParts[1])

    ProductId productId

    String name


// Class for product identifier.
class ProductId {
    String code
    String identifier

The following specification shows the data binding in action:

package mrhaki.grails.binding

import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification
import grails.databinding.SimpleMapDataBindingSource

class ProductSpec extends Specification {

    def dataBinder

    def setup() {
        // Use Grails data binding
        dataBinder = applicationContext.getBean('grailsWebDataBinder')

    void "productId parameter should be converted to a valid ProductId object"() {
        final Product product = new Product()

        final SimpleMapDataBindingSource source = 
            [productId: 'OFFCSPC-103910ab24', name: 'Swingline Stapler']

        dataBinder.bind(product, source)

        with(product) {
            name == 'Swingline Stapler'

            with(productId) {
                identifier == '103910ab24'
                code == 'OFFCSPC'


If we would have a controller with the request parameters productId=OFFCSPC-103910ab24&name=Swingline%20Stapler the data binding of Grails can create a Product instance and set the properties with the correct values.

Written with Grails 2.5.0 and 3.0.1.

Discover how the Force.com Web Services Connector (WSC) is a code-generation tool and runtime library for use with Force.com Web services, brought to you in partnership with Salesforce.


Published at DZone with permission of Hubert Klein Ikkink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}