【问题标题】:Grails Command Objects custom Validate Message CodesGrails 命令对象自定义验证消息代码
【发布时间】:2013-06-06 14:14:42
【问题描述】:

当使用命令对象时:

class UserCommand {

   String name

   static constraints = {
      name blank: false, unique: true, minSize: 3
   }
}

您可以使用它们来验证对象,而无需使它们持久化。在我的情况下,我将验证持久类用户。

在控制器中:

def save(UserCommand cmd) {
  if(!cmd.validate()) {
      render view: "create", model: [user: cmd]
  return
  }
  def user = new User()
  user.name = cmd.name
  user.save()

  redirect uri: '/'

} 

在messages.properties中:

user.username.minSize.error=Please enter at least three characters.
userCommand.username.minSize.error=Please enter at least three characters.

使用自定义验证消息时,您必须为每个错误编写两次消息代码。一个用于 User 类,另一个用于 UserCommand 类。

有没有办法让每个错误只有一个消息代码?

【问题讨论】:

  • 这真的是一个直观的问题,让我想如果我可以在UserCommand 的约束中使用属性importFrom User 来实现您所期望的。但不,它不能实现目标。最后,我认为您必须同时提供这两个消息。请参阅Validation and Internationalization,其中特别提到了类名。除非有另一种方法,否则我觉得您必须坚持以上才能在命令对象和域对象中应用验证。继承可能是我持怀疑态度的一个选项。

标签: validation grails grails-2.0 grails-domain-class grails-validation


【解决方案1】:

我在这里可能是错的,但如果您只使用 Grails 约束,共享验证消息的唯一方法是简单地依赖 messages.properties 中的 default.x.x.message 键/值。否则,将通过以下密钥形式查找消息:

className.propertyName.errorcode...=

但是,您可以使用 custom validator 并覆盖为验证错误返回的消息密钥。

class User {
  ...

  static constraints = {
    ...
    name blank: false, unique: true, validator: { value, user ->
      if(!value || value.length() < 3)
        return 'what.ever.key.in.messages.properties'
    }
  }
}

然后您可以通过global constraint 或@dmahapatro 提到的在类之间共享约束来保持所有内容干燥,就像这样在您的 UserCommand 中使用importFrom

class UserCommand {
 ...
 static constraints = {
   importFrom User
   ...
  }
}

如果您有更复杂的验证,您可以创建自己的约束类。以下是一些资源:

http://www.zorched.net/2008/01/25/build-a-custom-validator-in-grails-with-a-plugin/ http://blog.swwomm.com/2011/02/custom-grails-constraints.html

【讨论】:

  • 也想到了default 消息,但不想污染默认行为。它可能会影响其他领域。就自定义消息而言,我同意它是灵活的并且可以制作为 DRY,但是对于 OP 所指的所有这些约束,它必须再次完成。比如空白、独特等。对吧?
【解决方案2】:
  1. 在 CommandObject 中使用唯一约束没有意义,因为它会检查什么的唯一性?
  2. 您可以验证域对象,而无需使用与命令对象完全相同的方式持久化它们 - 使用 validate() 方法
  3. 你可以把一个用户对象放在命令对象中,只为域类设置约束,然后验证用户对象是命令对象的一部分

    class User { 
        String name
        static constraints = {
            name blank: false, unique: true, minSize: 3
        }
    }
    
    class UserCommand {
        User user 
        static constraints = {
            user validator: { it.validate() }
        }
    }
    
    user.username.minSize.error=Please enter at least three characters.
    

【讨论】:

  • 你打算如何将这个 URL 中的name 绑定到命令对象?http://localhost:8080/myapp/user/save?name=Fo。或者如果从表单提交,您将如何将name 绑定到命令对象?
  • 两种情况,参数/输入名称应该是user.name 所以http://localhost:8080/myapp/user/save?user.name=Fo
  • user.name 对终端客户意味着什么?
  • user是UserCommand类中User对象引用的名称,name是User类中的字段名
  • 是的。为什么该服务的消费者应该知道在服务器端完成的所有这些事情。他/她应该知道我必须在 URL 中发送一个名字。说得通? :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多