Grails 验证

 

验证

Grails的验证功能基于Spring's Validator API和数据绑定功能。不过,Grails利用这些特性,通过它的"constraints(约束)"机制, 提供了一个统一的定义验证约束方式。

Grails中的Constraints(约束)是用声明式指定效验规则的方式。常用于domain 类,不过 URL MappingsCommand 对象同样支持Constraints(约束)。

 

 

1 声明 Constraints(约束)

在一个domain类中,constraints(约束) 是通过给constraints属性赋值代码块的形式来定义的:

 

class User {
    String login
    String password
    String email
    Integer age

static constraints = { … } }

然后,通过与属性名匹配的方法调用,并结合命名参数来指定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) } }

在这个示例中,我们声明login属性必须在5-15个字符长度之间,不能为空,并且必须是唯一的。我们还可以为password,emailage属性运用其他的约束.

 

现有约束的完整参考可以在参考指南中找到

2 验证约束

验证基础

你可以在任何实体中调用validate方法验证domain:

 

def user =  new User(params)

if(user.validate()) { // do something with user } else { user.errors.allErrors.each { println it } }

domain的errors 属性是一个Spring Errors 接口实例. Errors 提供用于导航验证错误以及取回原始值的方法。

 

验证阶段

Grails中本质上有2个验证阶段,第一个阶段是 data binding ,当你把请求参数绑定到实体上发生,例如:

 

def user = new User(params)

这时,因为类型转换(如String转换为Dates),在errors属性可能已经出现错误。 你可以检查它们并通过使用ErrorsAPI获得原始输入值:

 

if(user.hasErrors()) {
	if(user.errors.hasFieldErrors("login")) {
		println user.errors.getFieldError("login").rejectedValue
	}
}

验证的第2阶段发生在当你调用 validatesave时。这时,Grails将会验证你在constraints 定义的约束值。比如,默认的持久方法save会在执行之前调用 validate 。因此,允许你像下面这样编码:

 

if(user.save()) {
    return user
}
else {
    user.errors.allErrors.each {
        println it
    }
}

 

3 客户端验证

显示错误

通常,当你得到一个验证错误后,你会重定向回页面渲染这些错误。这时,你就需要一些渲染错误的方法。 Grails 提供了一组丰富的标签,处理错误渲染。 如果只是想简单的渲染错误列表,可以使用renderErrors:

 

<g:renderErrors bean="${user}" />

假如,你需要更多的控制,可以使用 hasErrorseachError:

 

<g:hasErrors bean="${user}">
  <ul>
   <g:eachError var="err" bean="${user}">
       <li>${err}</li> 
   </g:eachError>
  </ul>
</g:hasErrors>

 

高亮错误

当一个字段存在错误的输入时,一个红色块和一些提示符,对于高亮错误非常有用。这时通过把 hasErrors 当做方法调用来做到。 比如:

 

<div class='value ${hasErrors(bean:user,field:'login','errors')}'>
   <input type="text" name="login" value="${fieldValue(bean:user,field:'login')}"/>
</div>

上面的代码做了什么?它会检查userlogin字段是否存在任何错误,如果存在,就给 div添加一个errors CSS class,这样就可以让你使用CSS来高亮div.

 

取回输入值

任何错误实际上是Spring中FieldError 类的实体,它会在内部保存原始输入值。通过fieldValue标签获取错误对象的原始输入值:

 

<input type="text" name="login" value="${fieldValue(bean:user,field:'login')}"/>

这段代码会查看,在User bean中是否存在一个 FieldError,如果是,就获取 login 字段的原始输入值。

4 验证与国际化

Grails中另一个关于errors值得注意的重要事情是:错误消息的显示,无需任何的硬编码。Spring中的 FieldError类使用Grails的 i18n 支持,基本上解决了来自消息绑定的消息。

 

规约与 Message 编码

编码它们自己通过规约来规定,例如,考虑早前看到约束:

 

package com.mycompany.myapp

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) } }

如果 blank约束不合法, Grails将在form中通过规约查找消息编码:

 

[Class Name].[Property Name].[Constraint Code]

在这种情况下, blank约束就会是 user.login.blank 因此,你需要在 grails-app/i18n/messages.properties文件中包含下面这样的消息:

 

user.login.blank=Your login name must be specified!

它会查找带package或不带package的类名,带有package的将会优先。作为示例,com.mycompany.myapp.User.login.blank 将先于 user.login.blank使用。 当你domain 类的消息编码与插件产生冲突时,可以这样使用。

每个规约的编码参考可以参考参考指南 constraints refer to the reference guide for each constraint.

 

显示消息

当你使用message标签时, renderErrors 标签将自动处理查找消息。 不过,假如你想获得更多的渲染控制,你需要自己编写代码:

 

<g:hasErrors bean="${user}">
  <ul>
   <g:eachError var="err" bean="${user}">
       <li><g:message error="${err}" /></li> 
   </g:eachError>
  </ul>
</g:hasErrors>

这个示例中, eachError 标签主体内,我们使用了 message 标签的 error 参数来读取给定的错误 。

 

5 验证非Domain 与命令行对象

Domain 类command objects(命令行对象)默认支持验证。其他类也可以在类中定义静态constraints 属性获得验证(如上所述),然后把它们告诉框架。 当应用程序在框架中注册验证类 是非常重要的。简单定义constraints属性是不够的。

 

Validateable 注解

任何定义了静态constraints属性和标有 @Validateable 接口的类可以在框架中被验证。考虑下面示例:

 

// src/groovy/com/mycompany/myapp/User.groovy
package com.mycompany.myapp

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) } }

默认情况下,框架会搜索所有带有@Validateable 注解的类。 你可以指定框架只搜索某个packages,通过给Config.groovy中的 grails.validateable.packages属性赋值一列字符串。

 

// grails-app/conf/Config.groovy

...

grails.validateable.packages = ['com.mycompany.dto', 'com.mycompany.util']

...

假如grails.validateable.packages属性被设置,框架只会在这些packages中搜索 (和它们的子 packages) 标有@Validateable的类.

 

注册Validateable类

假如一个类没有被标为@Validateable,它仍然可能通过框架验证。 那就是必须在类中定义静态constraints 属性 (如上所述) ,然后,通过在Config.groovy中为grails.validateable.classes属性设置值来告诉框架。

 

// grails-app/conf/Config.groovy

...

grails.validateable.classes = [com.mycompany.myapp.User, com.mycompany.dto.Account]

...

你可能感兴趣的:(spring,bean,框架,grails,groovy)