Пружина привязки: флажки для перечисления при отправке вызывают ошибку - PullRequest
7 голосов
/ 06 сентября 2011

Просто наполовину, я использую Java и Spring для веб-приложения.

У меня есть объект (objectBean), который содержит EnumSet (enumSet) типа EnumInnerObject в качестве атрибута. Я передаю этот объект как бин из моего контроллера в мой .jsp вид. Я использую следующий код .jsp для привязки флажков:

<form:form commandName="objectBean" name="whatever" action="./save.htm" method="post">
    <form:checkboxes items="${allOptions}" path="enumSet" />
</form:form>

Вот мой контроллер initbinder:

@InitBinder
protected void initBinder(WebDataBinder binder) throws Exception{
    binder.registerCustomEditor(EnumSet.class, "enumSet", new CustomCollectionEditor(Collection.class){
        protected Object convertElement(Object element){
            if(element instanceof String){
                EnumInnerObject enumInnerObject= EnumInnerObject.valueOf((String)element);
                return enumInnerObject;
            }
             return null;
         }
     });

В контроллере я передаю allOptions (отдельно от моего bean-компонента), и он содержит все параметры EnumInnerObject, поэтому отображаются все флажки. «enumSet» - это атрибут EnumSet с соответствующими значениями (если значение содержится в EnumSet, тогда он автоматически устанавливает правильный флажок в «allOptions»). Все это работает, и .jsp правильно показывает правильные флажки. Однако проблема заключается в том, когда я отправляю страницу для сохранения. Я получаю следующую ошибку:

java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String[]] to required type [java.util.EnumSet] for property 'enumSet': PropertyEditor [com.example.controller.MyController$1] returned inappropriate value]

У меня такое чувство, что мне нужно изменить InitBinder, чтобы заставить форму работать. Есть идеи ??

Спасибо!

1 Ответ

5 голосов
/ 07 сентября 2011

Честно говоря, я с трудом представляю, как эта идея будет работать: EnumSet коллекция предназначена для хранения значений перечислений, но на момент ее создания необходимо знать количество элементов в этом перечислении (= размер вселенной это ее условия).

CustomCollectionEditor передается класс коллекции в качестве аргумента конструктора, поэтому необходимо создать эту коллекцию, и она не будет выполнена по вышеуказанной причине. Более чем CustomCollectionEditor поддерживает только ограниченное количество целевых коллекций (ArrayList, TreeSet, LinkedHashSet, см. CustomCollectionEditor#createCollection()).

Чтобы не усложнять вещи, я предлагаю вам использовать общие коллекции, а не EnumSet. В противном случае вам нужно написать свой собственный редактор свойств. Реализация не будет сложной, что-то вроде:

binder.registerCustomEditor(EnumSet.class, "enumSet",
    new PropertyEditorSupport() {
        @Override
        public void setValue(Object value) {
            EnumSet<EnumInnerObject> set = EnumSet.noneOf(EnumInnerObject.class);

            for (String val: (String[]) value) {
                set.add(EnumInnerObject.valueOf(val));
            }

            super.setValue(set);
        }
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...