0

我想将自定义验证器添加到字段以强制执行有条件的非空约束。由于此要求在多个对象之间共享,因此我想重用现有的全局(意味着不是对象或字段特定的)消息键。在下面的示例中,我想使用default.null.message而不是类似objectA.fieldC.null.message.

Grails 验证器的文档似乎说,可以通过返回表示来自 message.properties 的键的字符串值来表示错误情况。该文件表明(强调我的):

闭包可以返回:

  • null 或 true(或无返回值)表示该值有效
  • false 表示无效值并使用默认消息代码
  • 一个字符串,指示要附加到“classname.propertyName”的错误代码。用于解决错误消息的字符串。如果无法解析特定于字段的消息,则将解析错误代码本身,以允许出现全局错误消息。
  • 一个包含上述字符串的列表,然后是后面的任意数量的参数,这些参数在 grails-app/i18n/message.properties 文件中用作格式化的消息参数。参数的映射如下:参数0到2自动映射为0:属性名,1:类名,2:属性值。其他参数从参数 3 开始映射。

我还发现在 1.0 中关闭的Grails 错误似乎几乎完全符合我的要求。

这是我正在做的一个例子。正如你所看到的,我有一种工作方法,但让我很烦恼的是,看似更干净的前两个选项不起作用。

class ObjectA {
    ObjectB fieldB
    ObjectC fieldC
    static constraints = {
        fieldC(nullable: true, validator: { value, object, errors ->
            if (object.fieldB != ObjectB.SOMETHING && !value) {
                // Doesn't work
                //return "default.null.message"
                
                // Doesn't work
                //return ["default.null.message"]

                // This works
                errors.rejectValue("defaultBrand", "default.null.message", ["defaultBrand"] as Object[], "The field \"{0}\" cannot be null")
            }
        })
    }
}

这是我的条目message.properties

default.null.message=The field "{0}" cannot be null

我在这里看到了几个与带有自定义错误消息的 Grails 自定义字段验证器相关的 问题,但似乎没有任何问题可以解决我的具体情况。

4

1 回答 1

0

当使用 validate 闭包的三参数(值、对象、错误)版本时,底层代码假定所有错误都将添加到错误对象中。为了返回代表消息键的字符串或字符串列表。

如果也使用命令对象,行为也是相同的。

这是一个双参数验证闭包的工作示例:

class ObjectA {
    ObjectB fieldB
    ObjectC fieldC
    static constraints = {
        fieldC(nullable: true, validator: { value, object->
            if (object.fieldB != ObjectB.SOMETHING && !value) {
                return "default.null.message"
                // You can also use the list style return (especially if you need to pass additional parameters used by the message)
                //return ["default.null.message"]
            }
        })
    }
}

这是一个三参数验证闭包的工作示例:

class ObjectA {
    ObjectB fieldB
    ObjectC fieldC
    static constraints = {
        fieldC(nullable: true, validator: { value, object, errors ->
            if (object.fieldB != ObjectB.SOMETHING && !value) {
                // When "errors" is passed into the closure, you must use it to signal error cases
                errors.rejectValue("defaultBrand", "default.null.message", ["defaultBrand"] as Object[], "The field \"{0}\" cannot be null")
            }
        })
    }
}
于 2014-04-18T18:36:10.890 回答