Validation 圣杯在哪里;s的错误属性来自哪里?

Validation 圣杯在哪里;s的错误属性来自哪里?,validation,grails,grails-2.0,Validation,Grails,Grails 2.0,Grails在数据绑定方面有一个缺陷,当您处理错误的数字输入时,它会抛出一个强制转换异常。吉拉: 为了解决这个问题,我编写了以下代码,手动处理位于src/groovy void setPrice(String priceStr) { this.priceString = priceStr // Remove $ and , priceStr = priceStr.trim().replaceAll(java.util.regex.Matcher.quoteReplac

Grails在数据绑定方面有一个缺陷,当您处理错误的数字输入时,它会抛出一个强制转换异常。吉拉:

为了解决这个问题,我编写了以下代码,手动处理位于
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()
呢?

这些错误会以友好的方式添加到您的可验证类(域类和具有注释
@validatable
的类)中

允许开发人员设置字符串而不是数字似乎不是一个好办法。此外,您的验证将仅对该特定类有效

我认为更好的方法是注册数字的自定义属性编辑器。下面是日期,它支持将
字符串
(从表单提交)转换为
日期,格式为dd/MM/yyyy。想法是一样的,因为您将强制执行您的数字是可解析的(例如,
Integer.parseInt()
将引发异常)


在域类中,使用数字类型而不是字符串,因此代码开发人员将不允许存储非数字值。

我不能确切地告诉您原因,但您需要显式调用
getErrors()
,而不是像属性一样将其作为
errors
访问。出于某种原因,Groovy没有为此调用方法。因此,将
setPrice()
中的
reject
行更改为

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

getErrors().rejectValue(
        'price',
        'trade.price.invalidformat')

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

AST转换处理
@Validateable

  • 名为
    errors
  • 公共方法
    getErrors
    setErrors
    clearErrors
    hasErrors
如果尚未设置
errors
字段,则
getErrors
方法会延迟设置该字段。因此,看起来正在发生的事情是,对同一类中
错误的访问被视为字段访问,而不是javabean属性访问,并绕过延迟初始化


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

Hrm,我必须掩盖POGO位,并假设它是一个域class@doelleri我认为同样的转换也适用于域类,您链接到的代码只针对那些在编译时没有增强的域类(这可能发生在开发模式自动重新编译中)。你应该得到接受,我只是在回答你的“我不能确切地告诉你为什么”:-)