Grails 2.5.6如何解析请求并将JSON映射到POGO? [英] How does Grails 2.5.6 parse and map request JSON to POGO?
问题描述
Tl; dr :我想在
感谢Jeff Scott Brown 把我带到那儿.
Tl;dr: I want to get test MyCmdTest."data bind works"
in this code green.
Thanks to Jeff Scott Brown for getting me that far.
我有一个POGO,其中包含一些来自JSON的自定义转换,我希望可以在Grails控制器中收到它们:
I have a POGO with some custom conversions from JSON which I expect to receive in a Grails controller:
def myAction(MyCmd myData) {
...
}
使用:
@Validateable
class MyCmd {
SomeType some
void setSome(Object value) {
this.some = customMap(value)
}
}
请注意customMap
如何从JSON值(例如,字符串)创建SomeType
的实例.假设默认设置器不起作用;例如,一个不止一次的模式就是这样的枚举:
Note how customMap
creates an instance of SomeType
from a JSON value (say, a String). Let's assume the default setter won't work; for instance, an pattern we have around more than once is an enum like this:
enum SomeType {
Foo(17, "foos"),
Bar(19, "barista")
int id
String jsonName
SomeType(id, jsonName) {
this.id = id
this.jsonName = jsonName
}
}
在这里,customMap
将采用整数或字符串,并返回匹配的大小写(如果不适合,则返回null
).
Here, customMap
would take an integer or string, and return the matching case (or null
, if none fits).
现在,我具有以下形式的单元测试:
Now, I have a unit test of the following form:
class RegistrationCmdTest extends Specification {
String validData // hard-coded, conforms to JSON schema
void test() {
MyCmd cmd = new MyCmd(JSON.parse(validData))
// check members: success
MyCmd cmd2 = JSON.parse(validData) as MyCmd
// check members: success
}
}
显然,在两个变体中都调用setSome
.
Apparently, setSome
is called in both variants.
我还有一个控制器单元测试,该测试将请求JSON设置为相同的字符串:
I also have a controller unit test that sets the request JSON to the same string:
void "register successfully"() {
given:
ResonseCmd = someMock()
when:
controller.request.method = 'POST'
controller.request.contentType = "application/json"
controller.request.json = validData
controller.myAction()
then:
noExceptionThrown()
// successful validations: service called, etc.
}
基本上,同一件事也可以作为集成测试.
Basically the same thing also runs as integration test.
但是,运行完整应用程序时,映射失败; some == null
.
However, the mapping fails when running the full application; some == null
.
我必须实现或重写哪些方法,以便Grails调用我的转换(此处为customMap
),而不是在不知道要做什么的地方插入null
?
Which methods do I have to implement or override so Grails calls my conversions (here, customMap
) instead of inserting null
where it doesn't know what to do?
推荐答案
可以使用@BindUsing
批注来自定义数据绑定:
It's possible to customize data binding using the @BindUsing
annotation:
@BindUsing({ newCmd, jsonMap ->
customMap(jsonMap['someType'])
})
SomeType someType
另请参见 MWE存储库
来源: Hubert Klein Ikkink @ DZone ,
Sources: Hubert Klein Ikkink @ DZone, Official Docs (there are other ways to customize)
这篇关于Grails 2.5.6如何解析请求并将JSON映射到POGO?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!