Grails 为什么可以';我是否在自定义字段验证器中返回全局消息键?

Grails 为什么可以';我是否在自定义字段验证器中返回全局消息键?,grails,gorm,grails-2.3,grails-validation,Grails,Gorm,Grails 2.3,Grails Validation,我想向字段中添加一个自定义验证器,以强制执行条件非空约束。由于这个需求是跨多个对象共享的,所以我希望重用现有的全局(不是特定于对象或字段的)消息键。在下面的示例中,我想使用default.null.message而不是类似于objectA.fieldC.null.message的东西 似乎是说,可以通过从message.properties返回表示键的字符串值来表示错误情况。文件表明(我的重点): 关闭可以返回: null或true(或无返回值)表示该值有效 false表示无效值并使用默认消息

我想向字段中添加一个自定义验证器,以强制执行条件非空约束。由于这个需求是跨多个对象共享的,所以我希望重用现有的全局(不是特定于对象或字段的)消息键。在下面的示例中,我想使用
default.null.message
而不是类似于
objectA.fieldC.null.message的东西

似乎是说,可以通过从message.properties返回表示键的字符串值来表示错误情况。文件表明(我的重点):

关闭可以返回:

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

下面是我正在做的一个例子。正如你所看到的,我有一种工作方法,但它真的让我感到不安,似乎更干净的前两个选项不起作用

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")
            }
        })
    }
}
这是我的
消息中的条目。属性

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

我在这里看到了一个与Grails自定义字段验证器相关的自定义错误消息,但似乎没有任何东西能够解决我的具体情况。

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

如果同时使用,则行为相同

以下是双参数验证闭包的工作示例:

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")
            }
        })
    }
}
下面是三参数验证闭包的工作示例:

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

答案来自一个重复的问题虽然两个问题的答案基本相同,但我不认为这应该被标记为重复。由于您提到的问题专门调用命令对象,我怀疑大多数人在寻找域验证问题的答案时,不一定会考虑从列表中选择它。域类和命令对象的约束是相同的。