您的位置:首页 > 大数据 > 人工智能

Grails 1.2参考文档速读(15):验证

2010-04-29 11:00 357 查看
在前面的几篇中,我们已经看到了Grails的验证框架带来的便利,现在让我们深入对其进行了解。和Grails的大多数特性一样,Grails的验证框架同样也是建立在Spring之上的,不同的是它是以Spring的验证和绑定API为基础。通过前面的内容,我们已经知道Domain Class、Command Object和URL Mappings都可以使用它,具体的形式就是“约束”。以Domain Class为例,我们回顾一下它的写法:
class User {
……
static constraints = {
……
}
}
同时,我们也知道,有些约束会影响到数据库模式的生成,它们是:nullable:验证是否可为null
inList:限制值在一个范围或集合内
maxSize(minSize):限制属性值大小,对应列大小
max(min):设定最大(小)值,属性必须是java.lang.Comparable
range:限定值范围,属性必须是java.lang.Comparable
scale:限定小数位
size:限定属性值大小范围
unique:限定唯一
其他的约束则有:blank:验证字符串是否为empty
creditCard:验证字符串是否为信用卡
email:验证字符串是否为邮件地址
url:验证字符串是否是URL
matches:匹配正则表达式
notEqual:不等于
如果这些预定义的约束无法满足要求,我们还可以使用validator约束进行自定义验证。其返回值决定了验证结果:boolean值:false:失败;true:成功
password1( validator: {
val, obj ->
obj.properties['password2'] == val})

字符串:返回错误码,在显示错误消息时用,对应“class.property.错误码”;返回null则表示成功
login(validator: {
if (!it.startsWith('boba'))
return ['invalid.bountyhunter']})

字符串列表:返回[错误码,参数1,参数2…],对应“错误消息+参数值”;返回null表示成功
otherProperty( validator: {
return ['custom.error', arg1, arg2] } )

验证的阶段有2:阶段1:数据绑定,验证Request参数是否可转换成对象属性。
阶段2:validate或save,save会调用validate。基于约束进行验证。
如果验证出错,获得错误的方法有:法1:
if(user.hasErrors()) {
if(user.hasFieldError("login")) {
println user.getFieldError("login").rejectedValue
}
}

法2:
user.errors.allErrors.each { println it }

在客户端显示错误消息的方法有:简单列举:<g:renderErrors bean="${user}" />
更多控制:<hasErrors>和<eachError>
单独显示并检索输入值:fieldValue
<div class='value ${hasErrors(bean:user,field:'login','errors')}'>
<input type="text" name="login"
value="${fieldValue(bean:user,field:'login')}"/>
</div>

这些内容其实在Grails根据Domain Class产生的页面代码中都有。Grails对国际化提供了支持,这一部分内容会在以后详谈,表现在验证部分,就是错误消息的国际化。对于国际化有所了解的人都知道,所谓的国际化实际就是不直接输出消息内容,而是以消息键取而代之,然后准备好支持目标语言的各种消息内容,在运行时根据Locale决定消息键的消息内容。验证中错误消息的键约定:Class.Property.Constraint,对于很多错误消息,Grails已经提供了缺省的内容,如果不满意,直接按约定覆盖即可。页面使用<g:message>来显示消息内容:
<g:hasErrors bean="${user}">
<ul>
<g:eachError var="err" bean="${user}">
<li><g:message error="${err}" /></li>
</g:eachError>
</ul>
</g:hasErrors>
Grails的验证能力还可以扩展到其他对象上去,具体步骤有2:在类中定义constraints静态属性
告知Grails框架
具体的操作,则有2种方法。方法1:将类用@Validateable注解
在类中定义constraints静态属性
import org.codehaus.groovy.grails.validation.Validateable
@Validateable
class User {
...
static constraints = {
login(size:5..15, blank:false, unique:true)
password(size:5..15, blank:false)
email(email:true, blank:false)
age(min:18, nullable:false)
}
}

在Config.groovy中定义要查找@Validateable的包名:grails.validateable.packages
grails.validateable.packages = ['com.mycompany.dto', 'com.mycompany.util']

方法2:在类中定义constraints静态属性
class User {
...
static constraints = {
login(size:5..15, blank:false, unique:true)
password(size:5..15, blank:false)
email(email:true, blank:false)
age(min:18, nullable:false)
}
}

在Config.groovy中注册类名: grails.validateable.classes
grails.validateable.classes = [com.mycompany.myapp.User
, com.mycompany.dto.Account]

但是在使用时,你必须注意(这是文档中没有的!):Grails会动态给这些类加入validate、hasErrors、getErrors、setErrors、clearErrors等方法。
在调用validate之后,如果validate为false,在重新进行validate之前,必需调用clearErrors。
在Domain Class上无需如此。
不信的话,大家可以试一试以下的代码(在Grails Console中运行即可):
def u= new foxgem.test1.User1(name:'')
assert u.validate() == false
u.name='foxgem'
assert u.validate() == false
u.clearErrors()
assert u.validate() == true
因为比较简单,具体内容就不列出了,只简要说明一下:User1不要放到domain目录下,这样Grails会把它当作domain class
name上的约束是:“blank:false”
最后,在独家报料一个文档上没有的内容,对Domain Class进行部分验证。这种需求产生的原因:有可能某个Domain Class是由多个Controller产生的,而每个Controller只关心部分属性,因此产生了部分验证的需要。解决办法:在validate中传入一个属性字符串列表,这时validate就只验证该列表中的属性。例子如下:
def p = new Person()
p.validate(['firstName', 'lastName', 'age'])
ps:这个技巧来自Grails用户组邮件列表,就在本文刚刚写完之时,该内容已经加入到了文档中;):http://hudson.grails.org/job/grails_core_1.2.x/ws/grails-doc/output/ref/Domain%20Classes/validate.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: