自定义Grails验证

时间:2011-04-10 17:23:52

标签: grails groovy grails-validation

通常对于Grails域或命令类,您声明约束,框架添加validate()方法,检查这些约束中的每一个是否对当前实例有效,例如。

class Adult {

  String name
  Integer age

  void preValidate() { 
    // Implementation omitted
  }

  static constraints = {
    name(blank: false)
    age(min: 18)
  }
}

def p = new Person(name: 'bob', age: 21)
p.validate()

在我的情况下,我想确保在验证类之前始终执行preValidate。我可以通过添加方法

来实现这一目标
def customValidate() {
  preValidate()
  validate()
}

但是,使用此课程的每个人都需要记得拨打customValidate而不是validate。我不能这样做

def validate() {
  preValidate()
  super.validate()
}

因为validate不是父类的方法(它是由元编程添加的)。还有另一种方法来实现我的目标吗?

2 个答案:

答案 0 :(得分:2)

当域/命令类具有preValidate()方法时,您应该能够通过在元类上使用自己的validate版本来实现此目的。您BootStrap.groovy中类似于以下代码的内容可能对您有用:

class BootStrap {

    def grailsApplication   // Set via dependency injection

    def init = { servletContext ->

        for (artefactClass in grailsApplication.allArtefacts) {
            def origValidate = artefactClass.metaClass.getMetaMethod('validate', [] as Class[])
            if (!origValidate) {
                continue
            }

            def preValidateMethod = artefactClass.metaClass.getMetaMethod('preValidate', [] as Class[])
            if (!preValidateMethod) {
                continue
            }

            artefactClass.metaClass.validate = {
                preValidateMethod.invoke(delegate)
                origValidate.invoke(delegate)
            }
        }
    }

    def destroy = {
    }
}

答案 1 :(得分:2)

您可以使用beforeValidate()事件完成目标。它在1.3.6 Release Notes中描述。