5.7. Other Action execution examples
Prev | 5. Executing actions | Next

## 5.7. Other Action execution examples

### on-start

The following example shows an action that creates a new Booking object by invoking a method on a service:

    <flow xmlns="http://www.springframework.org/schema/webflow"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/webflow
                              http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

        <input name="hotelId" />

        <on-start>
            <evaluate expression="bookingService.createBooking(hotelId, currentUser.name)"
                      result="flowScope.booking" />
        </on-start>

    </flow>

### on-entry

The following example shows a state entry action that sets the special `fragments` variable that causes the view-state to render a partial fragment of its view:

    <view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true">
        <on-entry>
            <render fragments="hotelSearchForm" />
        </on-entry>
    </view-state>

### on-exit

The following example shows a state exit action that releases a lock on a record being edited:

    <view-state id="editOrder">
        <on-entry>
            <evaluate expression="orderService.selectForUpdate(orderId, currentUser)"
                      result="viewScope.order" />
        </on-entry>
        <transition on="save" to="finish">
            <evaluate expression="orderService.update(order, currentUser)" />
        </transition>
        <on-exit>
            <evaluate expression="orderService.releaseLock(order, currentUser)" />
        </on-exit>
    </view-state>

### on-end

The following example shows the equivalent object locking behavior using flow start and end actions:

    <flow xmlns="http://www.springframework.org/schema/webflow"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/webflow
                              http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">

        <input name="orderId" />

        <on-start>
            <evaluate expression="orderService.selectForUpdate(orderId, currentUser)"
                      result="flowScope.order" />
        </on-start>

        <view-state id="editOrder">
            <transition on="save" to="finish">
                <evaluate expression="orderService.update(order, currentUser)" />
            </transition>
        </view-state>

        <on-end>
            <evaluate expression="orderService.releaseLock(order, currentUser)" />
        </on-end>

    </flow>

### on-render

The following example shows a render action that loads a list of hotels to display before the view is rendered:

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

### on-transition

The following example shows a transition action adds a subflow outcome event attribute to a collection:

    <subflow-state id="addGuest" subflow="createGuest">
        <transition on="guestCreated" to="reviewBooking">
            <evaluate expression="booking.guestList.add(currentEvent.attributes.newGuest)" />
        </transition>
    </subfow-state>

### Named actions

The following example shows how to execute a chain of actions in an action-state. The name of each action becomes a qualifier for the action's result event.

    <action-state id="doTwoThings">
        <evaluate expression="service.thingOne()">
            <attribute name="name" value="thingOne" />
        </evaluate>
        <evaluate expression="service.thingTwo()">
            <attribute name="name" value="thingTwo" />
        </evaluate>
        <transition on="thingTwo.success" to="showResults" />
    </action-state>

In this example, the flow will transition to `showResults` when `thingTwo` completes successfully.

### Streaming actions

Sometimes an Action needs to stream a custom response back to the client. An example might be a flow that renders a PDF document when handling a print event. This can be achieved by having the action stream the content then record "Response Complete" status on the ExternalContext. The responseComplete flag tells the pausing view-state not to render the response because another object has taken care of it.

    <view-state id="reviewItinerary">
        <transition on="print">
            <evaluate expression="printBoardingPassAction" />
        </transition>
    </view-state>

    public class PrintBoardingPassAction extends AbstractAction {
        public Event doExecute(RequestContext context) {
            // stream PDF content here...
            // - Access HttpServletResponse by calling context.getExternalContext().getNativeResponse();
            // - Mark response complete by calling context.getExternalContext().recordResponseComplete();
            return success();
        }
    }

In this example, when the print event is raised the flow will call the printBoardingPassAction. The action will render the PDF then mark the response as complete.

### Handling File Uploads

Another common task is to use Web Flow to handle multipart file uploads in combination with Spring MVC's `MultipartResolver`. Once the resolver is set up correctly as described here and the submitting HTML form is configured with `enctype="multipart/form-data"`, you can easily handle the file upload in a transition action. Given a form such as:

    <form:form modelAttribute="fileUploadHandler" enctype="multipart/form-data">
    	Select file: <input type="file" name="file"/>
    	<input type="submit" name="_eventId_upload" value="Upload" />
    </form:form>

and a backing object for handling the upload such as:

    package org.springframework.webflow.samples.booking;

    import org.springframework.web.multipart.MultipartFile;

    public class FileUploadHandler {

        private transient MultipartFile file;

        public void processFile() {
    		//Do something with the MultipartFile here
        }

        public void setFile(MultipartFile file) {
            this.file = file;
        }
    }

you can process the upload using a transition action as in the following example:

    <view-state id="uploadFile" model="uploadFileHandler">
        <var name="fileUploadHandler" class="org.springframework.webflow.samples.booking.FileUploadHandler" />
        <transition on="upload" to="finish" >
            <evaluate expression="fileUploadHandler.processFile()"/>
        </transition>
        <transition on="cancel" to="finish" bind="false"/>
    </view-state>

The `MultipartFile` will be bound to the `FileUploadHandler` bean as part of the normal form binding process so that it will be available to process during the execution of the transition action.

Prev | Up | Next
5.6. Action exceptions | Home | 6. Flow Managed Persistence