У Grails есть механизм привязки данных, который преобразует параметры запроса в свойства объекта разных типов. Мы можем настроить привязку данных по умолчанию различными способами. Один из них использует аннотацию @DataBinding
. Мы используем замыкание в качестве аргумента для аннотации, в которой мы должны вернуть преобразованное значение. Мы получаем два аргумента: первый — это объект, к SimpleMapDataBindingSource
применяется привязка данных, а второй — источник со всеми исходными значениями типа SimpleMapDataBindingSource
. Источником может быть, например, структура типа карты или параметры объекта запроса.
В следующем примере кода у нас есть класс Product
с классом ProductId
. Мы пишем пользовательскую привязку данных для преобразования значения String
с шаблоном {code}-{identifier}
в объект ProductId
:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
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 } |
Следующая спецификация показывает привязку данных в действии:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
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.
Ссылка: | Grails Good: привязка пользовательских данных с аннотацией @DataBinding от нашего партнера по JCG Хьюберта Иккинка в блоге JDriven . |