2010-10-19 42 views
0

我一直在玩春季web流量酒店預訂應用程序,並且已經擴展了一下,試圖更好地理解spring web流和JSF集成在一起。春季文檔在這個領域並不是很出色,我一直以爲印象是,直到你改變它們,事情纔會起作用,然後沒有明確的文檔描述它是如何工作的,所以你不知道你是如何破壞它的。JSF - Spring Web Flow - 在嵌套數據表中訪問「selectedRow」的問題

無論如何,希望您熟悉春季web流量酒店預訂示例應用程序。如果您不是,主流將接受搜索條件並返回酒店列表,然後可以選擇酒店並顯示其信息。我試圖擴展它,以便在查看酒店時,可以查看有關各個酒店房間的信息。

這裏是流代碼:

<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 - 

類型異常報告

消息

描述服務器遇到一個內部錯誤()阻止其完成此請求。

例外

org.springframework.web.util.NestedServletException:請求處理失敗;嵌套的異常是org.springframework.webflow.execution.ActionExecutionException:執行[AnnotatedAction @ 34f67 targetAction = [SetAction @ 4db694 name = flowScope.room,value = flowScope.hotel.rooms.selectedRow,type = [null]]時拋出的異常,屬性='map [[empty]]'在流程'main'的狀態'reviewHotel'中 - 動作執行屬性爲'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]],attributes = map [[empty]]]中state'reviewHotel'流'main' - 動作執行屬性爲'map [[empty]]'org.springframework.webflow.execution.ActionExecutor.execute(ActionExecutor.java:60) org.springframework.webflow.engine .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。簡歷(FlowExecutionImpl.java:259) org.springframework.webflow.executor.FlowExecutorImp l.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.E​​LExpression.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。執行.AnnotatedAction.execute(AnnotatedAction.java:145) org.springframework.webflow。執行.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 org.springframework.webflow.engine.impl.RequestControlContextImpl.execute(RequestControlContextImpl.java:214) org.springframework.webflow.engine.TransitionableState.handleEvent(TransitionableState.java :119) org.springfra 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(Flo wHandlerAdapter.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片段?

非常感謝,如果你已經得到這麼多,並閱讀和理解這一點!我儘量做到儘可能全面,但如果需要更多信息,請讓我知道。

哦是的和酒店作爲變量稱爲房間這是一個列表和getRooms:列表和setRooms(列表房間)方法。

回答

0

這是EL評估flowScope.hotel.rooms.selectedRow參考的問題。

從您的描述中,flowScope.hotel.rooms引用了實現List接口的對象。當EL遇到這樣的對象時,它假設以下引用是該列表中的索引 - 因此您可以執行類似操作:

myList[0] - 顯示第0個元素。

不幸的是,當你沒有整數引用時會中斷,所以flowScope.hotel.rooms.selectedRow給你一個numberFormatException,因爲它不能強制'selectedRow'爲一個整數。

解決的辦法是從列表中分離出想要引用的屬性。所以你的房間對象不應該實現List,而是實現getSelectedRow和getItems--它將返回迭代的實際列表。