2010-10-19 4 views
0

J'ai joué avec l'application de réservation d'hôtels pour le web printanier et je l'ai prolongée pour essayer de mieux comprendre comment JSF s'intègrent ensemble. La documentation du printemps n'est pas très bonne dans ce domaine et j'ai l'impression que les choses fonctionnent jusqu'à ce que vous les changiez et il n'y a pas de documentation claire décrivant comment cela fonctionne en premier lieu, donc vous ne savez pas comment vous l'avez cassé.JSF - Spring Web Flow - Problème d'accès à "selectedRow" dans des tables de données imbriquées

Quoi qu'il en soit, nous espérons que vous êtes familier avec l'application de réservation d'hôtel de flux de printemps web. Si ce n'est pas le cas, le flux principal accepte les critères de recherche et renvoie une liste d'hôtels, puis un hôtel peut être sélectionné, puis ses informations sont affichées. J'essaie de l'étendre afin que lorsque vous regardez un hôtel, vous puissiez voir des informations sur les chambres d'hôtel individuelles.

est le code ici pour le flux:

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

Lorsque vous sélectionnez un hôtel, il appelle un service de prix. Voici ce point de vue:

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

La vue displayPriceBreakdown affiche alors comment le prix a été calculé lorsque vous cliquez sur un prix de l'hôtel. Voici la vue config:

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

Le reviewHotel.xhtml qui montre les détails de l'hôtel et ses chambres ressemble à ceci:

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

avec le bit important étant dataTable utilisé pour afficher les chambres d'hôtel:

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

Les informations relatives à la chambre s'affichent correctement. Toutefois, lorsque l'utilisateur clique sur un prix, je souhaite afficher la liste de ventilation des prix pour la pièce sélectionnée. Voilà ce que j'espérais accomplir avec le:

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

Cependant quand je lance je reçois un NumberFormatException pour SelectedRow.

HTTP Status 500 - 

Type d'exception rapport

un message

Description Le serveur a rencontré une erreur interne() qui l'a empêché de remplir cette demande.

exception

org.springframework.web.util.NestedServletException: traitement Échec de la demande; l'exception imbriquée est org.springframework.webflow.execution.ActionExecutionException: Exception levée en cours d'exécution [AnnotatedAction @ 34f67 targetAction = [SetAction @ 4db694 nom = fluxScope.room, valeur = fluxScope.hotel.rooms.selectedRow, type = [null]], attributs = map [[vide]]] dans l'état 'reviewHotel' du flux 'main' - les attributs d'exécution de l'action étaient 'map [[vide]]' 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)

cause profonde

org.springframework.webflow.execution.ActionExecutionException: Exception levée en cours d'exécution [AnnotatedAction @ 34f67 targetAction = [SetAction @ 4db694 nom = fluxScope.room, valeur = fluxScope.hotel.rooms.selectedRow, type = [null]], attributs = map [[vide]]] dans état 'reviewHotel' de flow 'main' - les attributs d'exécution de l'action étaient 'map [[vide]]' 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.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) causes profondes

java.lang.NumberFormatException: Pour chaîne d'entrée: "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. exécution.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.springfra mework.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.resumeExécution (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)

Comment passer l'objet HotelRoom dans le fragment displayPriceBreakdown?

Un grand merci si vous avez obtenu ce point et lisez et comprenez ceci! J'ai essayé d'être aussi minutieux que possible mais si plus d'informations sont nécessaires s'il vous plaît faites le moi savoir. Oh oui et l'hôtel comme une variable appelé chambres qui est une liste et a getChambres: liste et setRooms (salles de liste) méthodes.

Répondre

0

Ceci est un problème avec l'évaluation EL de la référence flowScope.hotel.rooms.selectedRow.

De votre description, flowScope.hotel.rooms fait référence à un objet qui implémente l'interface List. Quand EL rencontre un tel objet, il suppose que la référence suivante est un index dans cette liste - ainsi vous pouvez faire quelque chose comme:

myList[0] - pour afficher le 0ème élément.

Malheureusement, cela casse lorsque vous n'avez pas de référence entière, donc flowScope.hotel.rooms.selectedRow vous donne une exception numberFormatException car il ne peut pas contraindre 'selectedRow' dans un entier.

Une solution consiste à séparer les propriétés que vous souhaitez référencer de la liste. Donc votre objet rooms ne doit pas implémenter List, mais implémenter getSelectedRow et getItems - qui retourne la liste actuelle pour l'itération.

Questions connexes