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:

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:

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"