Grails 2.5:domainObj.validate() 方法 returns false 当 domainObj.properties=params
Grails 2.5:domainObj.validate() method returns false when domainObj.properties=params
我正在尝试将我的 grails 应用程序从版本 1.3 升级到 2.5。我有一个域 class,其中一个字段是枚举。在控制器中,当我执行 domainObj.validate() 时,它总是 returns 错误。验证错误是 -
grails.validation.ValidationErrors: 1 个错误
字段 'typeEnum' 上的对象 'Parameter' 中的字段错误:拒绝值 [0];代码 [com.TypeEnum.typeMismatch.error,com.TypeEnum.typeMismatch,com.TypeEnum.typeMismatch.error,com.TypeEnum.typeMismatch,typeMismatch.com.TypeEnum,typeMismatch.pspValueTypeEnum,typeMismatch.com.TypeEnum,typeMismatch];参数 [typeEnum];默认消息 [无枚举常量 com.TypeEnum.0]
编辑:进一步分析,我发现问题不在于枚举,而是在执行 parameterObj.properties = params 时,parameterObj.validate() returns 错误。
在我使用 Grails 2.5 的代码中,
parameterObj.validate() //returns true
parameterObj.properties = params
// code to convert String from params to Enum object and assign it to parameterObj
parameterObj.enumField = MyEnumClass.getEnumByName(params.enumNameValue)
parameterObj.validate() //This always return false
注:以上两种情况的validate(),parameterObj的字段值完全相同
在 Grails 2.5 中使用域 class 上的属性有什么变化吗?
如果您更改您的视图,以便他们将枚举的 name() 作为参数值发送,那么数据绑定就可以开箱即用。
至少我一直都是这样使用枚举的。
带名称的枚举数据绑定()
<g:select name="typeEnum" from="${TypeEnum.values()}" value="${obj.typeEnum}"/>
grails 然后使用每个枚举值的 .name() 作为值,使用 .toString() 作为显示的文本。这将生成如下内容:
<select name="typeEnum">
<option value="STRING">String</option>
<option value="NUMBER">Number</option>
...
</select>
控制器中的数据绑定可以很好地与域或命令对象一起工作:
def save1(PsparameterCmd cmd) {
...
instance.properties = cmd.properties
}
def save2() {
...
instance.properties = params
}
自定义枚举数据绑定
或者,您可以使用自定义数据绑定将 ID 转换为枚举值。
有不同的方法(文档:http://docs.grails.org/2.5.0/guide/theWebLayer.html#dataBinding):
* 您可以为该类型注册一个全局数据绑定器(如果您在应用程序中大量使用该枚举)
* 您可以在该单个字段上指定 dataBinding 注释(用于单次使用)
class Psparameter implements java.io.Serializable {
@BindUsing({ obj, params ->
return TypeEnum.values().find({ it.id == params.int('typeId') })
})
TypeEnum typeEnum
...
}
或全局转换器:
import org.grails.databinding.converters.ValueConverter
class TypeEnumConverter implements ValueConverter {
boolean canConvert(value) {
value instanceof Integer
}
def convert(value) {
return TypeEnum.values().find({ it.id == value })
}
Class<?> getTargetType() {
TypeEnum
}
}
您必须在 resources.groovy
中注册
beans = {
typeEnumConverter(your.package.TypeEnumConverter)
}
注意:据我所知(并且刚刚测试过),没有像TypeEnum.getTypeEnumById(value)这样的通用方法。这就是为什么我在上面的示例中使用 TypeEnum.values() 上的查找。
经过一段时间的努力,我终于在 Grails 2.5 中找到了针对此行为的解决方案。这是我的解决方案和观察结果。再次粘贴我的问题代码以供参考:
parameterObj.validate() //returns true
parameterObj.properties = params
// code to convert String from params to Enum object and assign it to parameterObj
parameterObj.enumField = MyEnumClass.getEnumByName(params.enumNameValue)
parameterObj.validate() //This always return false
如果字段(如我示例中的 enumField)是枚举,则枚举字符串值应传递给域对象 (parameterObj) 而不是枚举对象。
例如,如果我的枚举是
enum TypeEnum {
STRING(0, "String"), NUMBER(1, "Number"), TIME(2, "Time")
...
}
然后要发送到 domainObj 的值是 "STRING" 或 "NUMBER",等等
在我的例子中,如果我在将参数分配给属性后用 "STRING" 更新 enumField,那么验证仍然是 returns false。例如,
parameterObj.properties = params
parameterObj.enumField = "STRING"
parameterObj.validate() // returns FALSE
所以我必须在执行 parameterObj.properties = params 之前更新 params 中的 enumField 以通过 validate() 方法获得正确的结果。因此,此序列中的以下代码可以正常工作。
params.enumField = "STRING"
parameterObj.properties = params
parameterObj.validate() // returns True as expected
早期版本的 Grails 不是这种情况,我的应用程序在 Grails 1.3.3 版本上运行多年
我正在尝试将我的 grails 应用程序从版本 1.3 升级到 2.5。我有一个域 class,其中一个字段是枚举。在控制器中,当我执行 domainObj.validate() 时,它总是 returns 错误。验证错误是 -
grails.validation.ValidationErrors: 1 个错误 字段 'typeEnum' 上的对象 'Parameter' 中的字段错误:拒绝值 [0];代码 [com.TypeEnum.typeMismatch.error,com.TypeEnum.typeMismatch,com.TypeEnum.typeMismatch.error,com.TypeEnum.typeMismatch,typeMismatch.com.TypeEnum,typeMismatch.pspValueTypeEnum,typeMismatch.com.TypeEnum,typeMismatch];参数 [typeEnum];默认消息 [无枚举常量 com.TypeEnum.0]
编辑:进一步分析,我发现问题不在于枚举,而是在执行 parameterObj.properties = params 时,parameterObj.validate() returns 错误。
在我使用 Grails 2.5 的代码中,
parameterObj.validate() //returns true
parameterObj.properties = params
// code to convert String from params to Enum object and assign it to parameterObj
parameterObj.enumField = MyEnumClass.getEnumByName(params.enumNameValue)
parameterObj.validate() //This always return false
注:以上两种情况的validate(),parameterObj的字段值完全相同
在 Grails 2.5 中使用域 class 上的属性有什么变化吗?
如果您更改您的视图,以便他们将枚举的 name() 作为参数值发送,那么数据绑定就可以开箱即用。
至少我一直都是这样使用枚举的。
带名称的枚举数据绑定()
<g:select name="typeEnum" from="${TypeEnum.values()}" value="${obj.typeEnum}"/>
grails 然后使用每个枚举值的 .name() 作为值,使用 .toString() 作为显示的文本。这将生成如下内容:
<select name="typeEnum">
<option value="STRING">String</option>
<option value="NUMBER">Number</option>
...
</select>
控制器中的数据绑定可以很好地与域或命令对象一起工作:
def save1(PsparameterCmd cmd) {
...
instance.properties = cmd.properties
}
def save2() {
...
instance.properties = params
}
自定义枚举数据绑定
或者,您可以使用自定义数据绑定将 ID 转换为枚举值。
有不同的方法(文档:http://docs.grails.org/2.5.0/guide/theWebLayer.html#dataBinding): * 您可以为该类型注册一个全局数据绑定器(如果您在应用程序中大量使用该枚举) * 您可以在该单个字段上指定 dataBinding 注释(用于单次使用)
class Psparameter implements java.io.Serializable {
@BindUsing({ obj, params ->
return TypeEnum.values().find({ it.id == params.int('typeId') })
})
TypeEnum typeEnum
...
}
或全局转换器:
import org.grails.databinding.converters.ValueConverter
class TypeEnumConverter implements ValueConverter {
boolean canConvert(value) {
value instanceof Integer
}
def convert(value) {
return TypeEnum.values().find({ it.id == value })
}
Class<?> getTargetType() {
TypeEnum
}
}
您必须在 resources.groovy
中注册beans = {
typeEnumConverter(your.package.TypeEnumConverter)
}
注意:据我所知(并且刚刚测试过),没有像TypeEnum.getTypeEnumById(value)这样的通用方法。这就是为什么我在上面的示例中使用 TypeEnum.values() 上的查找。
经过一段时间的努力,我终于在 Grails 2.5 中找到了针对此行为的解决方案。这是我的解决方案和观察结果。再次粘贴我的问题代码以供参考:
parameterObj.validate() //returns true
parameterObj.properties = params
// code to convert String from params to Enum object and assign it to parameterObj
parameterObj.enumField = MyEnumClass.getEnumByName(params.enumNameValue)
parameterObj.validate() //This always return false
如果字段(如我示例中的 enumField)是枚举,则枚举字符串值应传递给域对象 (parameterObj) 而不是枚举对象。 例如,如果我的枚举是
enum TypeEnum { STRING(0, "String"), NUMBER(1, "Number"), TIME(2, "Time") ... }
然后要发送到 domainObj 的值是 "STRING" 或 "NUMBER",等等
在我的例子中,如果我在将参数分配给属性后用 "STRING" 更新 enumField,那么验证仍然是 returns false。例如,
parameterObj.properties = params parameterObj.enumField = "STRING" parameterObj.validate() // returns FALSE
所以我必须在执行 parameterObj.properties = params 之前更新 params 中的 enumField 以通过 validate() 方法获得正确的结果。因此,此序列中的以下代码可以正常工作。
params.enumField = "STRING" parameterObj.properties = params parameterObj.validate() // returns True as expected
早期版本的 Grails 不是这种情况,我的应用程序在 Grails 1.3.3 版本上运行多年