grails验证嵌套命令对象不起作用
Posted
技术标签:
【中文标题】grails验证嵌套命令对象不起作用【英文标题】:grails validate nested command object not working 【发布时间】:2013-04-17 09:22:43 【问题描述】:我正在使用 grails 2.2.1 并尝试验证嵌套的命令结构。这是我的命令对象的简化版本:
@Validateable
class SurveyCommand
SectionCommand useful
SectionCommand recommend
SurveyCommand()
useful = new SectionCommand(
question: 'Did you find this useful?',
isRequired: true)
recommend = new SectionCommand(
question: 'Would you recommend to someone else?',
isRequired: false)
@Validateable
class SectionCommand
String question
String answer
boolean isRequired
static constraints =
answer(validator: answerNotBlank, nullable: true)
static answerNotBlank = String val, SectionCommand obj ->
if(obj.isRequired)
return val != null && !val.isEmpty()
当我尝试验证 SurveyCommand
的实例时,无论部分值如何,它总是返回 true
,并且我在 SectionCommand
(answerNotBlank
) 中的自定义验证器永远不会被调用。从 grails 文档看来,this kind of nested structure is supported(deepValidate
默认为 true)。但是,也许这条规则只适用于域对象而不适用于 Command 对象?还是我只是在这里遗漏了什么?
【问题讨论】:
【参考方案1】:对于 Grails 2.3 及更高版本,我发现Cascade Validation Plugin 很好地解决了这个问题。它定义了一个名为 cascade 的新验证器类型,它完全符合您的期望。安装后,您的示例将变为:
class SurveyCommand
...
static constraints =
useful(cascade: true)
recommend(cascade: true)
【讨论】:
目前唯一可用的版本是:compile ":cascade-validation:0.1.4"
运行单元测试时,级联约束未注册到 grails。要解决此问题,必须将以下代码添加到测试的 setup() 方法中:ConstrainedProperty.registerNewConstraint(CascadeValidationConstraint.NAME, CascadeValidationConstraint)
。来源:github.com/rmorrise/grails-cascade-validation【参考方案2】:
您可以向主命令对象添加自定义验证器
@Validateable
class SurveyCommand
SectionCommand useful
SectionCommand recommend
static subValidator = val, obj ->
return val.validate() ?: 'not.valid'
static constraints =
useful(validator: subValidator)
recommend(validator: subValidator)
SurveyCommand()
useful = new SectionCommand(
question: 'Did you find this useful?',
isRequired: true)
recommend = new SectionCommand(
question: 'Would you recommend to someone else?',
isRequired: false)
【讨论】:
不错!效果很好,但是有没有更干的方法而不是为每个子属性显式定义约束?【参考方案3】:如果您尝试使用mockForConstraintsTest()
从unit
测试validation
,那么您应该在Config.groovy
中注册command
对象,而不是使用@Validateable
,因为现有Grails Bug。详情请参考SO question/answers。
您可以在Config.groovy
中注册如下可验证的类
grails.validateable.classes =
[yourpackage.SurveyCommand, yourpackage.SectionCommand]
【讨论】:
它 似乎 可以正常工作(在 2.2.1 中)通过在实例化之前调用mockCommandObject
来测试 @Validatable
命令类的 .validate()
方法,例如mockCommandObject SurveyCommand
同意。这就是我之前提到的 SO 问题/答案的方法。 mockCommandObject
有效,但 mockForConstraintsTest
失败。
啊,明白了,谢谢你的澄清。显然我读得不够仔细以上是关于grails验证嵌套命令对象不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Grails、Vaadin 7 和 SpringSecurity:授权不起作用
Grails 监视文件在 Vagrant 虚拟机中运行的 Docker 容器中不起作用