Тег флажка Spring MVC, привязанный к коллекции, ожидает объект, но проверка ожидает object.id - PullRequest
1 голос
/ 18 ноября 2010

В моем проекте Spring MVC у меня есть страница обновления для Class1, на которой должен отображаться список формы: теги-флажки, связанные с коллекцией объектов в Class1.

Class1.java:

class Class1 {
  private Set<Class2> set;
  //... other fields 
}

В updateclass1.jspx:

<c:forEach items="${allClass2Instances}" var="class2">
   <form:checkbox label="${class2.name}" path="set" value="${class2}"/><br/>
</c:forEach>

С тегом-флажком, как указано выше, при отображении страницы флажок отмеченесли экземпляр Class2 является частью Set для class1, и не отмечен, если это не так.Но когда я нажимаю «отправить», я получаю следующую ошибку:

Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.Set' for property 'set'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "Name 1" from type 'java.lang.String' to type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "Name1"

Насколько я могу судить, когда страница заполнена, тегу form: checkbox нужен экземпляр, чтобы установить правильное проверенное / непроверенное значение,но при отправке JSP отправляет массив значений class2.toString () преобразователю, который ожидает идентификаторы.И наоборот, когда я изменяю тег на следующий:

<form:checkbox label="${class2.name}" path="set" value="${class2.id}"/><br/>

Привязка работает нормально, но когда я просматриваю страницу обновления, флажки не отмечены / не отмечены правильно, потому что тег не знает, что значение передается вявляется идентификатором объекта.

Как сделать привязку после отправки согласованной с тем, что ожидает тег checkbox?

В случае, если это имеет значение - все это внутри страницы скаффолдинга, сгенерированной Roo.

1 Ответ

0 голосов
/ 18 ноября 2010

Разобрался, как заставить это работать на данный момент. Если кто-нибудь придумает более точное решение, добавьте его, и я вместо этого отмечу его правильным.

Проблема, описанная выше, была вызвана необходимостью $ {InstanceOfClass2} для оценки разных вещей в разных местах:

  1. Во время оценки тега, <form:checkbox> требовалось выражение, которое оценивалось для фактического экземпляра Class2
  2. После завершения тега атрибут значения сгенерированного тега <input type="checkbox"> должен быть равен полю числового идентификатора экземпляра Class2

Решением было добавить конвертер в мой Class1Controller, например:

Converter<Class2, String> getClass2Converter() {
    return new Converter<Class2, String>() {
        public String convert(Class2 instance) {
            return "" + instance.getId();
        }
    };
}

Таким образом, выражение $ {InstanceOfClass2} оценивает экземпляр Class2 для тега флажка, но когда дело доходит до записи, фактический HTML преобразуется в числовой идентификатор.

Этот подход очень грязный при работе с Roo. Все остальные леса, относящиеся к Class1, затем захотят использовать этот же конвертер, поэтому я начал везде видеть целую кучу идентификаторов, которые вы хотели бы видеть Class2.name или другие подобные поля. Я решил эту проблему, изменив пользовательский тег Spring Roo <field:display> - добавил атрибут fmtCollectionToString, который, если присутствует, заставляет тег оценивать коллекции, повторяя их и вызывая toString для каждого элемента, вместо вызова spring:eval в целом коллекция, которая также, кажется, заканчивается тем, что вызывается конвертер.

Как я уже сказал, более аккуратные решения очень ценятся! Если есть способ заставить преобразователи вести себя по-разному, например, в разных обстоятельствах - все равно захотите это услышать.

...