Grails有关于数据绑定的错误,因为当你处理错误的数字输入时它会抛出一个强制转换异常。 JIRA:http://jira.grails.org/browse/GRAILS-6766
为了解决这个问题,我编写了以下代码来手动处理位于Foo
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()
属性?
答案 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
getErrors
,setErrors
,clearErrors
和hasErrors
getErrors
方法懒惰地设置errors
字段(如果尚未设置)。所以看起来正在发生的事情是,对同一类中的errors
的访问被视为字段访问而不是Java Bean属性访问,并绕过延迟初始化。
因此修复似乎是使用getErrors()
而不仅仅是errors
。
答案 2 :(得分:2)
错误将添加到您的可验证类(具有注释@Validateable
的域类和类)中。
允许开发人员设置字符串而不是数字似乎不是一个好方法。此外,您的验证仅适用于该特定类。
我认为更好的方法是为数字注册自定义属性编辑器。这是带有日期的a example,可以使用dd / MM / yyyy等格式将String
(从表单中提交)转换为Date
。这个想法是一样的,因为你会强制你的号码是可解析的(例如。Integer.parseInt()
会抛出异常)。
在您的域类中,使用数字类型而不是String,因此代码开发人员不允许存储数字值。