10.4. Implementing custom FlowHandlers
Prev | 10. Spring MVC Integration | Next

## 10.4. Implementing custom FlowHandlers

`FlowHandler` is the extension point that can be used to customize how flows are executed in a HTTP servlet environment. A `FlowHandler` is used by the `FlowHandlerAdapter` and is responsible for:

- Returning the `id` of a flow definition to execute

- Creating the input to pass new executions of that flow as they are started

- Handling outcomes returned by executions of that flow as they end

- Handling any exceptions thrown by executions of that flow as they occur

These responsibilities are illustrated in the definition of the `org.springframework.mvc.servlet.FlowHandler` interface:

    public interface FlowHandler {

        public String getFlowId();

        public MutableAttributeMap createExecutionInputMap(HttpServletRequest request);

        public String handleExecutionOutcome(FlowExecutionOutcome outcome,
            HttpServletRequest request, HttpServletResponse response);

        public String handleException(FlowException e,
            HttpServletRequest request, HttpServletResponse response);
    }

To implement a FlowHandler, subclass `AbstractFlowHandler`. All these operations are optional, and if not implemented the defaults will apply. You only need to override the methods that you need. Specifically:

- Override `getFlowId(HttpServletRequest)` when the id of your flow cannot be directly derived from the HTTP request. By default, the id of the flow to execute is derived from the pathInfo portion of the request URI. For example, `http://localhost/app/hotels/booking?hotelId=1` results in a flow id of `hotels/booking` by default.

- Override `createExecutionInputMap(HttpServletRequest)` when you need fine-grained control over extracting flow input parameters from the HttpServletRequest. By default, all request parameters are treated as flow input parameters.

- Override `handleExecutionOutcome` when you need to handle specific flow execution outcomes in a custom manner. The default behavior sends a redirect to the ended flow's URL to restart a new execution of the flow.

- Override `handleException` when you need fine-grained control over unhandled flow exceptions. The default behavior attempts to restart the flow when a client attempts to access an ended or expired flow execution. Any other exception is rethrown to the Spring MVC ExceptionResolver infrastructure by default.

### Example FlowHandler

A common interaction pattern between Spring MVC And Web Flow is for a Flow to redirect to a @Controller when it ends. FlowHandlers allow this to be done without coupling the flow definition itself with a specific controller URL. An example FlowHandler that redirects to a Spring MVC Controller is shown below:

    public class BookingFlowHandler extends AbstractFlowHandler {
        public String handleExecutionOutcome(FlowExecutionOutcome outcome,
                                             HttpServletRequest request, HttpServletResponse response) {
            if (outcome.getId().equals("bookingConfirmed")) {
                return "/booking/show?bookingId=" + outcome.getOutput().get("bookingId");
            } else {
                return "/hotels/index";
            }
        }
    }

Since this handler only needs to handle flow execution outcomes in a custom manner, nothing else is overridden. The `bookingConfirmed` outcome will result in a redirect to show the new booking. Any other outcome will redirect back to the hotels index page.

### Deploying a custom FlowHandler

To install a custom FlowHandler, simply deploy it as a bean. The bean name must match the id of the flow the handler should apply to.

    <bean name="hotels/booking" class="org.springframework.webflow.samples.booking.BookingFlowHandler" />

With this configuration, accessing the resource `/hotels/booking` will launch the `hotels/booking` flow using the custom BookingFlowHandler. When the booking flow ends, the FlowHandler will process the flow execution outcome and redirect to the appropriate controller.

### FlowHandler Redirects

A FlowHandler handling a FlowExecutionOutcome or FlowException returns a `String` to indicate the resource to redirect to after handling. In the previous example, the `BookingFlowHandler` redirects to the `booking/show` resource URI for `bookingConfirmed` outcomes, and the `hotels/index` resource URI for all other outcomes.

By default, returned resource locations are relative to the current servlet mapping. This allows for a flow handler to redirect to other Controllers in the application using relative paths. In addition, explicit redirect prefixes are supported for cases where more control is needed.

The explicit redirect prefixes supported are:

- `servletRelative:` - redirect to a resource relative to the current servlet

- `contextRelative:` - redirect to a resource relative to the current web application context path

- `serverRelative:` - redirect to a resource relative to the server root

- `http://` or `https://` - redirect to a fully-qualified resource URI

These same redirect prefixes are also supported within a flow definition when using the `externalRedirect:` directive in conjunction with a view-state or end-state; for example, `view="externalRedirect:http://springframework.org"`

Prev | Up | Next
10.3. Dispatching to flows | Home | 10.5. View Resolution