Я поигрался с приложением для бронирования отелей 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).