Validation 圣杯在哪里;s的错误属性来自哪里?
Grails在数据绑定方面有一个缺陷,当您处理错误的数字输入时,它会抛出一个强制转换异常。吉拉: 为了解决这个问题,我编写了以下代码,手动处理位于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
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我认为同样的转换也适用于域类,您链接到的代码只针对那些在编译时没有增强的域类(这可能发生在开发模式自动重新编译中)。你应该得到接受,我只是在回答你的“我不能确切地告诉你为什么”:-)