Grail的错误属性来自哪里?

Jim*_*ace 4 validation grails grails-2.0

Grails有关于数据绑定的错误,因为当你处理错误的数字输入时它会抛出一个强制转换异常.JIRA:http://jira.grails.org/browse/GRAILS-6766

为了解决这个问题,我编写了以下代码来手动处理Foo位于的POGO类的数字输入src/groovy

void setPrice(String priceStr)
{
    this.priceString = priceStr

    // Remove $ and , 
    priceStr = priceStr.trim().replaceAll(java.util.regex.Matcher.quoteReplacement('$'),'').replaceAll(',','')

    if (!priceStr.isDouble()) {
        errors.reject(
            'trade.price.invalidformat',
            [priceString] as Object[],
            'Price:[{0}] is an invalid price.')

        errors.rejectValue(
            'price',
            'trade.price.invalidformat')
    } else {
        this.price = priceStr.toDouble();
    }
}
Run Code Online (Sandbox Code Playgroud)

以下命令会在该errors.reject()行上引发空引用异常.

foo.price = "asdf" // throws null reference on errors.reject()
foo.validate()
Run Code Online (Sandbox Code Playgroud)

但是,我可以说:

foo.validate()
foo.price = "asdf" // no Null exception
foo.hasErrors() // false
foo.validate()
foo.hasErrors() // true
Run Code Online (Sandbox Code Playgroud)

validate()调用时错误从何而来?有没有办法在errorsvalidate()先调用的情况下添加属性?

doe*_*eri 6

我不能确切地告诉你原因,但你需要getErrors()明确地调用而不是errors像属性一样访问它.出于某种原因,Groovy没有为它调用方法.因此,将reject行更改setPrice()

getErrors().reject(
        'trade.price.invalidformat',
        [priceString] as Object[],
        'Price:[{0}] is an invalid price.')

getErrors().rejectValue(
        'price',
        'trade.price.invalidformat')
Run Code Online (Sandbox Code Playgroud)

这是确保Errors方法中存在对象的最简单方法.您可以查看将验证相关方法添加到域类的代码.


Ian*_*rts 5

除了其他方面, AST转换处理@Validateable 增强了类

  • 一个名为的字段 errors
  • 公共方法getErrors,setErrors,clearErrorshasErrors

如果尚未getErrors设置该errors字段,该方法会懒惰地设置该字段.所以看起来正在发生的事情是,errors在同一个类中的访问被视为字段访问而不是Java Bean属性访问,并绕过延迟初始化.

所以修复似乎是使用getErrors()而不是仅仅errors.