JSF - Spring Web Flow - проблема с доступом к «selectedRow» во вложенных таблицах данных - PullRequest
0 голосов
/ 19 октября 2010

Я поигрался с приложением для бронирования отелей Spring Web Flow и немного расширил его, чтобы попытаться лучше понять, как Spring Web Flow и JSF интегрируются друг с другом. Весенняя документация не так уж хороша в этой области, и у меня сложилось впечатление, что все работает, пока вы не измените их, а затем нет четкой документации, описывающей, как она работала в первую очередь, поэтому вы не знаете, как ее сломали.

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

вот код для потока:

    <view-state id="reviewHotels">
    <on-render>
        <evaluate expression="bookingService.findHotels(searchCriteria, flowRequestContext)" result="viewScope.hotels" result-type="dataModel" />
    </on-render>
    <transition on="select" to="reviewHotel">
        <set name="flowScope.hotel" value="hotels.selectedRow" />
    </transition>

Когда вы выбираете отель, он вызывает услугу ценообразования. Вот это мнение:

<view-state id="reviewHotel" model="hotel">
    <on-render>
        <evaluate expression="bookingService.priceHotel(flowScope.hotel, flowRequestContext)" result="flowScope.hotel"/>
    </on-render>

    <transition on="price" to="displayPriceBreakdown">
        <set name="flowScope.room" value="flowScope.hotel.rooms.selectedRow"></set>
    </transition>
</view-state>

Представление displayPriceBreakdown затем отображает, как была рассчитана цена при нажатии на цену отеля. Вот конфиг вида:

    <view-state id="displayPriceBreakdown" view="displayPriceBreakdown.xhtml">
    <on-entry>
        <render fragments="priceBreakdownFragment" />
    </on-entry>
    <transition on="back" to="reviewHotel"/>
</view-state>

ReviewHotel.xhtml, который показывает информацию об отеле и его номерах, выглядит так:

<ui:define name="content">
<div class="section">
<h2>View Hotel</h2>
<ui:fragment id="messages">
        <div id="messagesInsertionPoint">
            <h:messages errorClass="errors" />
        </div>
</ui:fragment>

<h:form id="hotel">
    <fieldset>
        <div class="field">
            <div class="labelhotel">Name:</div>
            <div class="outputhotel">#{hotel.name}</div>
        </div>
        <div class="field">
            <div class="labelhotel">Address:</div>
            <div class="outputhotel">#{hotel.address}</div>
        </div>
        <div class="field">
            <div class="labelhotel">City:</div>
            <div class="outputhotel">#{hotel.city}</div>
        </div>
        <div class="field">
            <div class="labelhotel">Post Code:</div>
            <div class="outputhotel">#{hotel.zip}</div>
        </div>
        <div class="field">
            <div class="labelhotel">Country:</div>
            <div class="outputhotel">#{hotel.country}</div>
        </div>
        <div class="field">
            <div class="labelhotel">Amenities:</div>
            <div class="outputhotel"><h:dataTable id="amentities" var="a" value="#{hotel.amenities}">
                                    <h:column>#{a.name} - #{a.description}</h:column></h:dataTable></div>
        </div>

        <div class="field">
            <div class="labelhotel">Rooms:</div>
            <ui:fragment id="roomsFragment">
            <div class="outputhotel"><h:dataTable id="rooms" styleClass="summary" var="r" value="#{hotel.rooms}">
                                    <h:column>#{r.roomType} - #{r.bedType}</h:column> 
                                    <h:column><sf:commandLink id="priceBreakdownLink" value="#{r.roomPrice} #{r.roomPriceCurrency}" action="price" processIds="priceBreakdownFragment"/> </h:column>
                                    <h:column><sf:commandLink id="bookHotelLink" value="Book Hotel" action="select"/></h:column>
                                </h:dataTable>
            </div>
            </ui:fragment>
        </div>

        <div class="buttonGroup">
            <h:commandButton id="cancel" action="cancel" value="Back to Search"/>
        </div>
    </fieldset>
</h:form>

, причем важным битом является таблица данных, используемая для отображения гостиничных номеров:

            <div class="field">
            <div class="labelhotel">Rooms:</div>
            <ui:fragment id="roomsFragment">
            <div class="outputhotel"><h:dataTable id="rooms" styleClass="summary" var="r" value="#{hotel.rooms}">
                                    <h:column>#{r.roomType} - #{r.bedType}</h:column> 
                                    <h:column><sf:commandLink id="priceBreakdownLink" value="#{r.roomPrice} #{r.roomPriceCurrency}" action="price" processIds="priceBreakdownFragment"/> </h:column>
                                    <h:column><sf:commandLink id="bookHotelLink" value="Book Hotel" action="select"/></h:column>
                                </h:dataTable>
            </div>
            </ui:fragment>
        </div>

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

        <transition on="price" to="displayPriceBreakdown">
        <set name="flowScope.room" value="flowScope.hotel.rooms.selectedRow"></set>
    </transition>

Однако когда я запускаю, я получаю NumberFormatException для selectedRow.

HTTP Status 500 -

тип Отчет об исключении

сообщение

description Сервер обнаружил внутреннюю ошибку (), которая не позволила ему выполнить этот запрос.

исключение

org.springframework.web.util.NestedServletException: обработка запроса не удалась; Вложенное исключение - org.springframework.webflow.execution.ActionExecutionException: исключение, вызванное выполнением = map [[empty]]] в состоянии 'reviewHotel' потока 'main' - атрибуты выполнения действия были 'map [[empty]]' org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:583) org.springframework.web.servlet.FrameworkServlet.doPost (FrameworkServlet.java:511) javax.servlet.http.HttpServlet.service (HttpServlet.java:637) javax.servlet.http.HttpServlet.service (HttpServlet.java:717) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter.java:96) org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:76) первопричина

org.springframework.webflow.execution.ActionExecutionException: исключение при выполнении [AnnotatedAction @ 34f67 targetAction = [SetAction @ 4db694 name = flowScope.room, value = flowScope.hotel.rooms.selectedRow, type = [null]], атрибуты = map [[empty]]] в состоянии 'reviewHotel' потока 'main' - атрибуты выполнения действия были 'map [[empty]]' org.springframework.webflow.execution.ActionExecutor.execute (ActionExecutor.java:60) org.springframework.webflow.engine.support.ActionTransitionCriteria.test (ActionTransitionCriteria.java:82) org.springframework.webflow.engine.support.TransitionCriteriaChain.test (TransitionCriteriaChain.java:71) org.springframework.webflow.engine.Transition.canExecute (Transition.java:195) org.springframework.webflow.engine.Transition.execute (Transition.java:211) org.springframework.webflow.engine.impl.FlowExecutionImpl.execute (FlowExecutionImpl.java:391) org.springframework.webflow.engine.impl.RequestControlContextImpl.execute (RequestControlContextImpl.java:214)org.springframework.webflow.engine.TransitionableState.handleEvent (TransitionableState.java:119) org.springframework.webflow.engine.Flow.handleEvent (Flow.java:555) org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent (FlowExecutionImpl.java:386) org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent (RequestControlContextImpl.java:210) org.springframework.webflow.engine.ViewState.handleEvent (ViewState.java:230) org.springframework.webflow.engine.ViewState.resume (ViewState.java:196) org.springframework.webflow.engine.Flow.resume (Flow.java:545) org.springframework.webflow.engine.impl.FlowExecutionImpl.resume (FlowExecutionImpl.java:259) org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution (FlowExecutorImpl.java:163) org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle (FlowHandlerAdapter.java:183) org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:875) org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:807) org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:571) org.springframework.web.servlet.FrameworkServlet.doPost (FrameworkServlet.java:511) javax.servlet.http.HttpServlet.service (HttpServlet.java:637) javax.servlet.http.HttpServlet.service (HttpServlet.java:717) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter.java:96) org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:76) первопричина

java.lang.NumberFormatException: для входной строки: "selectedRow" java.lang.NumberFormatException.forInputString (NumberFormatException.java:48) java.lang.Integer.parseInt (Integer.java:449) java.lang.Integer.parseInt (Integer.java:499) javax.el.ListELResolver.coerce (ListELResolver.java:166) javax.el.ListELResolver.getValue (ListELResolver.java:51) javax.el.CompositeELResolver.getValue (CompositeELResolver.java:54) org.springframework.binding.expression.el.DefaultELResolver.getValue (DefaultELResolver.java:80) org.jboss.el.parser.AstPropertySuffix.getValue (AstPropertySuffix.java:53) org.jboss.el.parser.AstValue.getValue (AstValue.java:67) org.jboss.el.ValueExpressionImpl.getValue (ValueExpressionImpl.java:186) org.springframework.binding.expression.el.BindingValueExpression.getValue (BindingValueExpression.java:54) org.springframework.binding.expression.el.ELExpression.getValue (ELExpression.java:54) org.springframework.webflow.action.SetAction.doExecute (SetAction.java:75) org.springframework.webflow.action.AbstractAction.execute (AbstractAction.java:188) org.springframework.webflow.execution.AnnotatedAction.execute (AnnotatedAction.java:145) org.springframework.webflow.execution.ActionExecutor.execute (ActionExecutor.java:51) org.springframework.webflow.engine.support.ActionTransitionCriteria.test (ActionTransitionCriteria.java:82) org.springframework.webflow.engine.support.TransitionCriteriaChain.test (TransitionCriteriaChain.java:71) org.springframework.webflow.engine.Transition.canExecute (Transition.java:195) org.springframework.webflow.engine.Transition.execute (Transition.java:211) org.springframework.webflow.engine.impl.FlowExecutionImpl.execute (FlowExecutionImpl.java:391) org.springframework.webflow.engine.impl.RequestControlContextImpl.execute (RequestControlContextImpl.java:214) org.springframework.webflow.engine.TransitionableState.handleEvent (TransitionableState.java:119) org.springframework.webflow.engine.Flow.handleEvent (Flow.java:555) org.springframework.webflow.engine.impl.FlowExecutionImpl.handleEvent (FlowExecutionImpl.java:386) org.springframework.webflow.engine.impl.RequestControlContextImpl.handleEvent (RequestControlContextImpl.java:210) org.springframework.webflow.engine.ViewState.handleEvent (ViewState.java:230)org.springframework.webflow.engine.ViewState.resume (ViewState.java:196) org.springframework.webflow.engine.Flow.resume (Flow.java:545) org.springframework.webflow.engine.impl.FlowExecutionImpl.resume (FlowExecutionImpl.java:259) org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution (FlowExecutorImpl.java:163) org.springframework.webflow.mvc.servlet.FlowHandlerAdapter.handle (FlowHandlerAdapter.java:183) org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:875) org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:807) org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:571) org.springframework.web.servlet.FrameworkServlet.doPost (FrameworkServlet.java:511) javax.servlet.http.HttpServlet.service (HttpServlet.java:637) javax.servlet.http.HttpServlet.service (HttpServlet.java:717) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal (CharacterEncodingFilter.java:96) org.springframework.web.filter.OncePerRequestFilter.doFilter (OncePerRequestFilter.java:76)

Как передать объект HotelRoom во фрагмент displayPriceBreakdown?

Большое спасибо, если вы зашли так далеко и читаете и понимаете это! Я старался быть максимально тщательным, однако, если требуется дополнительная информация, пожалуйста, дайте мне знать.

О, да и Hotel как переменная, называемая rooms, которая является List и имеет методы getRooms: List и setRooms (List rooms).

1 Ответ

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

Это проблема с оценкой EL для ссылки flowScope.hotel.rooms.selectedRow.

Из вашего описания flowScope.hotel.rooms ссылается на объект, который реализует интерфейс List.Когда EL встречает такой объект, он предполагает, что следующая ссылка является индексом в этом списке - так что вы можете сделать что-то вроде:

myList[0] - для отображения 0-го элемента.

К сожалению, это происходит, когда у вас нет целочисленной ссылки, поэтому flowScope.hotel.rooms.selectedRow дает вам исключение numberFormatException, поскольку оно не может привести 'selectedRow' к целому числу.

Решение состоит в том, чтобы выделить свойстваВы хотите ссылку из списка.Таким образом, ваш объект комнаты не должен реализовывать List, а должен реализовывать getSelectedRow и getItems - который возвращает фактический список для итерации.

...