Перечень коллекции Grails - PullRequest
       16

Перечень коллекции Grails

1 голос
/ 27 августа 2011

В моем приложении 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 автоматически выполняет преобразование параметра param -> enum на основе имени enum. Просто так бывает, я попытался определить редактор свойств, который выполняет это преобразование:

class RelationshipStatusEnumEditor extends PropertyEditorSupport {    

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

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

Я зарегистрировал этот редактор в Grails / Spring и попробовал снова, но результат был тот же. Можно ли привязать параметры запроса к Collection из Enum?

Ответы [ 2 ]

1 голос
/ 23 января 2014

Используя механизм ввода данных, представленный в Grails 2.3, я предложил следующее решение для преобразования параметров запроса в коллекцию перечислений.Например, учитывая эти перечисления

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 в качестве bean-компонента Spring в resources.groovy - не имеет значения, какое имя вы выбираете для bean-компонента.Затем, чтобы использовать приведенный выше класс для преобразования строки, разделенной запятыми, в коллекцию num, аннотируйте соответствующие свойства с помощью

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

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

. Значение, переданное @BindingFormat, должно быть простым именем типа перечисления, котороебудет храниться в связанной коллекции.

0 голосов
/ 27 августа 2011

Как я знаю, 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
...