Grails绑定收集枚举 [英] Grails bind collection enum

查看:174
本文介绍了Grails绑定收集枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  public enum RelationshipStatus {

Single_Never_Married ,
分居,
离婚,
丧偶;
}

我已经定义了这个命令对象:

  class MyCommand {
列表< RelationshipStatus>关系状态
}

我在我的一个控制器操作中使用

  def myAction = {MyCommand myCommand  - > 
}

当我通过参数提交此操作的请求

  user.relationshipStatuses = Separated& user.relationshipStatuses =离婚

我希望 myCommand.relationshipStatuses 将包含 RelationshipStatus.Separated RelationshipStatus.Divorced ,但实际上它是空的。



我的理解是Grails自动执行请求参数 - >枚举转换枚举的名字。只是这样,它没有,我尝试定义一个属性编辑器进行这种转换:

  class RelationshipStatusEnumEditor extends PropertyEditorSupport {

public String getAsText(){
value.name()
}

public void setAsText(String text){
RelationshipStatus.valueOf文本)
}
}

我用Grails / Spring注册了这个编辑器,再次尝试,但结果是一样的。是否可以将请求参数绑定到枚举的集合

解决方案

使用介绍的数据绑定Grails 2.3,我想出了将请求参数转换为枚举的集合的以下解决方案。例如,给定这些枚举

 枚举性别{
MALE,FEMALE
}

enum季节{
春季,夏季,秋季,冬季
}

和这个命令对象

  class MyCommand {
Collection< Gender>性别
集合<季节>季节
}

,假设我们要转换像 MALE,FEMALE春天,夏天,冬天到相应的枚举集合。首先,提供执行转换的 FormattedValueConverter 的实现

 类EnumCollectionConverter实现FormattedValueConverter {

/ **
*要使其他枚举可绑定,只需将它们添加到此列表中
* /
private static final List< Class&Enum> > convertableEnums = [性别,季节]

@Override
对象转换(值,字符串格式){

类&枚举> targetEnumClass = convertableEnums.find {it.simpleName == format}

if(targetEnumClass){
列表< String> enumConstantNames = value.toString()。tokenize(',')
return enumConstantNames.collect {targetEnumClass.valueOf(it)}
}

}

@Override
类<?> getTargetType(){

//此类转换为集合< T扩展枚举< T>>但是该方法的返回值
//不能比Collection更具体,因为类型为erasure
集合
}
}

然后在 resources.groovy中注册 EnumCollectionConverter 作为Spring bean - 您为该bean选择的名称无关紧要。然后使用上面的类将逗号分隔的字符串转换为num集合,用

 类MyCommand { 
@BindingFormat('Gender')
集合<性别>性别

@BindingFormat('Season')
集合< Season>季节
}

传递给 @BindingFormat 应该是将被存储在绑定集合中的枚举类型的简单名称。


In my grails app, I have this enum:

public enum RelationshipStatus{

  Single_Never_Married, 
  Separated,
  Divorced, 
  Widowed;  
}

I've defined this command object:

class MyCommand {
  List<RelationshipStatus> relationshipStatuses
}

which I use in one of my controller actions

def myAction = {MyCommand myCommand ->
}

when I submit a request to this action with parameters

user.relationshipStatuses=Separated&user.relationshipStatuses=Divorced

I expect that myCommand.relationshipStatuses will contain RelationshipStatus.Separated and RelationshipStatus.Divorced, but in fact it is null.

My understanding is that Grails automatically performs request param -> enum conversion based on the enum's name. Just it case it doesn't, I tried defining a property editor that does this conversion:

class RelationshipStatusEnumEditor extends PropertyEditorSupport {    

    public String getAsText() {
        value.name()
    }

    public void setAsText(String text) {
        RelationshipStatus.valueOf(text)
    }
}

I registered this editor with Grails/Spring and tried again, but the result was the same. Is it possible to bind request parameters to a Collection of Enum?

解决方案

Using the databinder introduced in Grails 2.3, I came up with the following solution for converting request params to collection of enums. For example, given these enums

enum Gender {
    MALE, FEMALE
}

enum Season {
    SPRING, SUMMER, AUTUMN, WINTER
}

and this command object

class MyCommand {
    Collection<Gender> genders
    Collection<Season> seasons
}

and assume we want to convert strings like "MALE,FEMALE" and "SPRING,SUMMER,WINTER" to the corresponding enum collections. Firstly, provide an implementation of FormattedValueConverter that does the conversion

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

Then register EnumCollectionConverter as a Spring bean in resources.groovy - it doesn't matter what name you choose for the bean. Then to use the class above to convert a comma-separated string to an num collection, annotate the relevant properties with

class MyCommand {
    @BindingFormat('Gender')
    Collection<Gender> genders

    @BindingFormat('Season')
    Collection<Season> seasons
}

The value passed to the @BindingFormat should be the simple name of the enum type that will be stored in the bound collection.

这篇关于Grails绑定收集枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆