Grail的错误属性来自哪里?

时间:2013-03-11 18:38:48

标签: 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();
    }
}

以下内容在errors.reject()行引发空引用异常。

foo.price = "asdf" // throws null reference on errors.reject()
foo.validate()

但是,我可以说:

foo.validate()
foo.price = "asdf" // no Null exception
foo.hasErrors() // false
foo.validate()
foo.hasErrors() // true

调用validate()时错误来自哪里? 有没有办法在不先调用errors的情况下添加validate()属性?

3 个答案:

答案 0 :(得分: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')

这是确保方法中存在Errors对象的最简单方法。您可以check out the code将与验证相关的方法添加到您的域类中。

答案 1 :(得分:5)

AST转换处理@Validateable augments the class with, among other things

  • 名为errors
  • 的字段
  • 公开方法getErrorssetErrorsclearErrorshasErrors

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

因此修复似乎是使用getErrors()而不仅仅是errors

答案 2 :(得分:2)

错误将添加到您的可验证类(具有注释@Validateable的域类和类)中。

允许开发人员设置字符串而不是数字似乎不是一个好方法。此外,您的验证仅适用于该特定类。

我认为更好的方法是为数字注册自定义属性编辑器。这是带有日期的a example,可以使用dd / MM / yyyy等格式将String(从表单中提交)转换为Date。这个想法是一样的,因为你会强制你的号码是可解析的(例如。Integer.parseInt()会抛出异常)。

在您的域类中,使用数字类型而不是String,因此代码开发人员不允许存储数字值。