Grails的绑定集合枚举
问题描述:
在我的Grails应用程序,我有这样的枚举:Grails的绑定集合枚举
public enum RelationshipStatus{
Single_Never_Married,
Separated,
Divorced,
Widowed;
}
我定义这个命令对象:
class MyCommand {
List<RelationshipStatus> relationshipStatuses
}
,我在我的控制器动作
一个使用def myAction = {MyCommand myCommand ->
}
当我提交一个请求到这个动作的参数
user.relationshipStatuses=Separated&user.relationshipStatuses=Divorced
我预计myCommand.relationshipStatuses
将包含RelationshipStatus.Separated
和RelationshipStatus.Divorced
,但实际上它是空的。
我的理解是,Grails根据枚举的名称自动执行请求参数 - >枚举转换。只要将它区分它不,我试图定义一个属性编辑器,做这种转换:
class RelationshipStatusEnumEditor extends PropertyEditorSupport {
public String getAsText() {
value.name()
}
public void setAsText(String text) {
RelationshipStatus.valueOf(text)
}
}
我注册这个编辑器使用Grails/Spring和再次尝试,但结果是一样的。是否可以将请求参数绑定到Enum的Collection?
答
使用Grails的2.3引入了DataBinder的,我想出了以下解决方案转换请求参数来收集的枚举。例如,考虑到这些枚举
enum Gender {
MALE, FEMALE
}
enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
和该命令对象
class MyCommand {
Collection<Gender> genders
Collection<Season> seasons
}
,我们假定我们要转换为字符串像"MALE,FEMALE"
和"SPRING,SUMMER,WINTER"
到相应的枚举集合。首先,提供FormattedValueConverter
的实现,确实
class EnumCollectionConverter implements FormattedValueConverter {
/**
* To make other enums bindable, just add them to this list
*/
private static final List<Class<Enum>> convertableEnums = [Gender, Season]
@Override
Object convert(value, String format) {
Class<Enum> targetEnumClass = convertableEnums.find { it.simpleName == format }
if (targetEnumClass) {
List<String> enumConstantNames = value.toString().tokenize(',')
return enumConstantNames.collect { targetEnumClass.valueOf(it) }
}
value
}
@Override
Class<?> getTargetType() {
// this class converts to a Collection<T extends Enum<T>> but the return value
// of this method can't be any more specific than Collection due to type erasure
Collection
}
}
然后注册EnumCollectionConverter
在resources.groovy
一个Spring bean转换 - 没关系什么名字,你选择这个bean。然后使用类以上用逗号分隔的字符串转换为NUM集合,
class MyCommand {
@BindingFormat('Gender')
Collection<Gender> genders
@BindingFormat('Season')
Collection<Season> seasons
}
注释相关属性传递给@BindingFormat
值应该是将存储在枚举类型的简单名称绑定的集合。
答
正如我所知,如果它是空的,默认情况下grails不会填充List属性。只有它已经存在,并且项目的索引被传递。
尝试定义这个属性为:
import org.apache.commons.collections.ListUtils
import org.apache.commons.collections.Factory
class MyCommand {
List<RelationshipStatus> relationshipStatuses = ListUtils.lazyList([],{new RelationshipStatus()} as Factory)
}
,并提交参数为:
user.relationshipStatuses[0]=Separated&user.relationshipStatuses[1]=Divorced
我相信,Grails不知道如何填充你的列表,因为它放弃了列表类型(List)上的信息。我不确定,如果可能的话。 –
sbglasius