Spring Список привязки данных типа интерфейса - как? - PullRequest
4 голосов
/ 23 января 2012

Пытался найти ответ в Интернете, но не смог.Должно быть просто для профессиональных разработчиков Spring ... так что вот оно:

В двух словах я хочу связать список типа интерфейса: список с формой и получить данные обратно (возможно, изменены пользователем через формуПроблема в том, что он не работает: (

мой код (короткая версия) - класс команды / модели, который передается в форму:

public class RoomsFormSearchResultCommand extends RoomsFormSearchCommand {
    @SuppressWarnings("unchecked")
    private List<IRoom> roomsList = LazyList.decorate(new ArrayList<Room>(),
            FactoryUtils.instantiateFactory(Room.class));

    public List<IRoom> getRoomsList() {
        return roomsList;
    }

    public void setRoomsList(final List<IRoom> roomsList) {
        this.roomsList = roomsList;
    }

(...)

, затем в форме Iиспользуйте это так (короткая версия):

    <form:form method="post" action="reserve" commandName="roomsResultsCmd">
(...)
    <c:forEach var="room" items="${roomsResultsCmd.roomsList}"
                varStatus="status">
                <tr>
                    <td><form:input path="roomsList[${status.index}].roomNumber" readonly="true"/>
(...)

Форма отображается нормально, но после отправки я получаю:

2012-01-22 21:31:55 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [wyspa] in context with path [/wyspa] threw exception [Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'roomsList[0]' of bean class [com.wyspa.controller.command.RoomsFormSearchResultCommand]: Illegal attempt to get property 'roomsList' threw exception; nested exception is org.springframework.beans.NullValueInNestedPathException: Invalid property 'roomsList' of bean class [com.wyspa.controller.command.RoomsFormSearchResultCommand]: Could not instantiate property type [com.wyspa.entity.IRoom] to auto-grow nested property path: java.lang.InstantiationException: com.wyspa.entity.IRoom] with root cause
org.springframework.beans.NullValueInNestedPathException: Invalid property 'roomsList' of bean class [com.wyspa.controller.command.RoomsFormSearchResultCommand]: Could not instantiate property type [com.wyspa.entity.IRoom] to auto-grow nested property path: java.lang.InstantiationException: com.wyspa.entity.IRoom
    at org.springframework.beans.BeanWrapperImpl.newValue(BeanWrapperImpl.java:633)
    at org.springframework.beans.BeanWrapperImpl.growCollectionIfNecessary(BeanWrapperImpl.java:863)
    at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:770)
    at org.springframework.beans.BeanWrapperImpl.getNestedBeanWrapper(BeanWrapperImpl.java:555)

(...)

Дело в том, что когда я изменяю список на список «экземпляров», все работает отлично!

public class RoomsFormSearchResultCommand extends RoomsFormSearchCommand {
    @SuppressWarnings("unchecked")
//notice that the List is now List<Room>
    private List<Room> roomsList = LazyList.decorate(new ArrayList<Room>(),
            FactoryUtils.instantiateFactory(Room.class));

В этом случае данные передаются в контроллер надлежащим образом.

Поскольку я привык использовать интерфейсы, и мне это безумно нравится, я бы ДЕЙСТВИТЕЛЬНО предпочел не переводить List<IRoom> (который возвращается из сервисов) в List<Room>, который, кажется, подходит для Spring. Возможно ли работатьс List<IRoom> в этом случае или Spring просто не поддерживает его?

// КонечноКомната реализует IRoom - но я думаю, вы уже получили это ...

Я был бы ОЧЕНЬ рад за любую помощь / предложения!

С наилучшими пожеланиями, Nirwan

Ответы [ 3 ]

3 голосов
/ 10 ноября 2012

У меня точно такая же проблема. Переход к следующему не решит проблему. Похоже, пружинное связывание игнорирует утилиты фабрики и пытается создать экземпляр самого нулевого объекта:

@SuppressWarnings("unchecked")
private List<IRoom> roomsList = LazyList.decorate(new ArrayList<IRoom>(),
    FactoryUtils.instantiateFactory(Room.class));

Обходной путь - отключить в вашем контроллере автоматический рост вложенного пути:

@InitBinder protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
    binder.setAutoGrowNestedPaths(false);
    super.initBinder(request, binder);
 }

Проблема в том, что вы потеряете удобный вложенный путь, например user.account.address.street. Вы должны убедиться, что ни один из пользователей, учетных записей, адресов не имеет значения. Это вызывает много проблем. Вот почему я пришел сюда, посмотреть, смогу ли я найти лучшее решение.

1 голос
/ 24 августа 2013

Если вам на самом деле не нужен список для автоматического увеличения, вы можете сохранить объект формы в сеансе, чтобы избежать неприятных побочных эффектов отключения автоматически растущих вложенных путей.

@Controller
@SessionAttributes(types = RoomsFormSearchResultCommand.class)
public final class SearchController {

    @InitBinder
    protected void initBinder(final WebDataBinder binder) {
            binder.setAutoGrowNestedPaths(false);
    }

    @RequestMapping(method = RequestMethod.GET)
    public String showForm(final Model model) {
            RoomsFormSearchResultCommand form = ... // create or load form
            model.addAttribute(form); 
    }

    @RequestMapping(method = RequestMethod.POST)
    public String onSubmitUpdateCart(
                    @ModelAttribute final RoomsFormSearchResultCommand form,
                    final BindingResult result,
                    final SessionStatus status) {
            // if result has no errors, just set status to complete
            status.setComplete();
    }
}
0 голосов
/ 16 февраля 2012

Попробуйте следующие строки

@SuppressWarnings("unchecked")
private List<IRoom> roomsList = LazyList.decorate(new ArrayList<IRoom>(),
    FactoryUtils.instantiateFactory(Room.class));

У меня нет времени, чтобы попробовать это самостоятельно, но это имело бы смысл.

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