0

私はSpring Web Flowのホテル予約アプリケーションをいじってみましたが、Spring Web FlowとJSFがどのように統合されるかをよりよく理解するために少し拡張しました。春のドキュメントはこの分野ではそれほど優れていません.変更するまで物事は機能し、最初にどのように機能したかを説明する明確なドキュメントがないため、どのように壊れたのかわかりません.

とにかく、Spring Web Flow のホテル予約サンプル アプリケーションに慣れていることを願っています。そうでない場合、メイン フローは検索基準を受け入れ、ホテルのリストを返します。その後、ホテルを選択して、その情報を表示できます。ホテルを見ているときに、個々のホテルの部屋に関する情報を表示できるように拡張しようとしています。

フローのコードは次のとおりです。

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

重要なのは、ホテルの部屋を表示するために使用される dataTable です。

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

ただし、実行すると、selectedRow の NumberFormatException が発生します。

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]]] in state 'reviewHotel' of flow '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.

org.springframework.webflow.execution.ActionExecutionException: [AnnotatedAction@34f67 targetAction = [SetAction@4db694 name = flowScope.room, value = flowScope.hotel.rooms.selectedRow, type = [null]], attributes = 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.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.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.サービス(HttpServlet.java:717) org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96) org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

HotelRoom オブジェクトを displayPriceBreakdown フラグメントに渡すにはどうすればよいですか?

ここまで来て、これを読んで理解しているなら、どうもありがとう!できる限り詳しく記載するように努めましたが、さらに詳しい情報が必要な場合はお知らせください。

そうそう、Hotel は、リストであり、 getRooms : List および setRooms(List rooms) メソッドを持つ、rooms という名前の変数です。

4

1 に答える 1

0

これは、flowScope.hotel.rooms.selectedRowリファレンスのEL評価の問題です。

説明からflowScope.hotel.rooms、Listインターフェースを実装するオブジェクトを参照します。ELがそのようなオブジェクトに遭遇すると、次の参照がそのリストへのインデックスであると想定します。したがって、次のようなことができます。

myList[0]--0番目の要素を表示します。

残念ながら、整数参照がないと壊れます。整数にflowScope.hotel.rooms.selectedRow''を強制できないため、numberFormatExceptionが発生します。selectedRow

解決策は、参照するプロパティをリストから分離することです。したがって、roomsオブジェクトはListを実装するのではなく、getSelectedRowとgetItemsを実装する必要があります。これは反復の実際のリストを返します。

于 2010-11-23T12:00:02.430 に答える