Grails具有数据绑定机制,可以将请求参数转换为不同类型的对象的属性。 我们可以通过不同方式自定义默认数据绑定。 其中之一是使用@DataBinding
批注。 我们使用闭包作为注解的参数,在注解中必须返回转换后的值。 我们得到两个参数,第一个是数据绑定应用到的对象,第二个是所有原始值都为SimpleMapDataBindingSource
类型的SimpleMapDataBindingSource
。 源可以是例如地图之类的结构或请求对象的参数。
在下一个示例代码中,我们有一个带有ProductId
类的Product
类。 我们编写了一个自定义数据绑定,将模式为{code}-{identifier}
的String
值转换为ProductId
对象:
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
}
以下规范显示了实际的数据绑定:
package mrhaki.grails.binding
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import spock.lang.Specification
import grails.databinding.SimpleMapDataBindingSource
@TestMixin(GrailsUnitTestMixin)
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"() {
given:
final Product product = new Product()
and:
final SimpleMapDataBindingSource source =
[productId: 'OFFCSPC-103910ab24', name: 'Swingline Stapler']
when:
dataBinder.bind(product, source)
then:
with(product) {
name == 'Swingline Stapler'
with(productId) {
identifier == '103910ab24'
code == 'OFFCSPC'
}
}
}
}
如果我们有一个带有请求参数productId=OFFCSPC-103910ab24&name=Swingline%20Stapler
的控制器,则Grails的数据绑定可以创建一个Product
实例,并使用正确的值设置属性。
用Grails 2.5.0和3.0.1编写。