flow handler simplification
This commit is contained in:
@@ -3,14 +3,12 @@ package org.springframework.webflow.samples.booking;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
import org.springframework.webflow.core.collection.AttributeMap;
|
||||
import org.springframework.webflow.mvc.servlet.AbstractFlowHandler;
|
||||
|
||||
public class BookingFlowHandler extends AbstractFlowHandler {
|
||||
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
public String handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return new ModelAndView(new RedirectView("/spring/hotels/index", true));
|
||||
return "/spring/hotels/index";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public interface ExternalContext {
|
||||
* @param flowExecutionKey the flow execution key
|
||||
* @return the flow execution URL
|
||||
*/
|
||||
public String getFlowExecutionUri(String flowId, String flowExecutionKey);
|
||||
public String getFlowExecutionUrl(String flowId, String flowExecutionKey);
|
||||
|
||||
/**
|
||||
* Provides access to the user's principal security object.
|
||||
|
||||
@@ -50,6 +50,13 @@ public interface FlowUrlHandler {
|
||||
*/
|
||||
public void setFlowExecutionInSession(String flowExecutionKey, RenderRequest request);
|
||||
|
||||
/**
|
||||
* Creates a flow execution URL suitable for use as an action URL.
|
||||
* @param flowId the flow id
|
||||
* @param flowExecutionKey the flow execution key
|
||||
* @param response the render response
|
||||
* @return the execution url
|
||||
*/
|
||||
public String createFlowExecutionUrl(String flowId, String flowExecutionKey, RenderResponse response);
|
||||
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ public class PortletExternalContext implements ExternalContext {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getFlowExecutionUri(String flowId, String flowExecutionKey) {
|
||||
public String getFlowExecutionUrl(String flowId, String flowExecutionKey) {
|
||||
if (this.isRenderPhase()) {
|
||||
return flowUrlHandler.createFlowExecutionUrl(flowId, flowExecutionKey, (RenderResponse) response);
|
||||
} else {
|
||||
|
||||
@@ -191,7 +191,7 @@ public class ServletExternalContext implements ExternalContext {
|
||||
return ajaxRequest;
|
||||
}
|
||||
|
||||
public String getFlowExecutionUri(String flowId, String flowExecutionKey) {
|
||||
public String getFlowExecutionUrl(String flowId, String flowExecutionKey) {
|
||||
return flowUrlHandler.createFlowExecutionUrl(flowId, flowExecutionKey, request);
|
||||
}
|
||||
|
||||
|
||||
@@ -174,7 +174,7 @@ class RequestControlContextImpl implements RequestControlContext {
|
||||
public String getFlowExecutionUrl() {
|
||||
String key = flowExecution.getKey() != null ? flowExecution.getKey().toString() : null;
|
||||
if (key != null) {
|
||||
return externalContext.getFlowExecutionUri(flowExecution.getDefinition().getId(), key);
|
||||
return externalContext.getFlowExecutionUrl(flowExecution.getDefinition().getId(), key);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,7 @@ public class AbstractFlowHandler implements FlowHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ModelAndView handleFlowOutcome(String outcome, AttributeMap output, RenderRequest request,
|
||||
RenderResponse response) {
|
||||
public String handleFlowOutcome(String outcome, AttributeMap output, RenderRequest request, RenderResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -58,10 +58,10 @@ public interface FlowHandler {
|
||||
* @param output the output returned by the flow execution
|
||||
* @param request the current render request
|
||||
* @param response the current render response
|
||||
* @return the model and view to render on the occurrence of this outcome, or null if the outcome was not handled
|
||||
* @return the id of the flow to start after handling the outcome, or null if the outcome should be handled by the
|
||||
* caller
|
||||
*/
|
||||
public ModelAndView handleFlowOutcome(String outcome, AttributeMap output, RenderRequest request,
|
||||
RenderResponse response);
|
||||
public String handleFlowOutcome(String outcome, AttributeMap output, RenderRequest request, RenderResponse response);
|
||||
|
||||
/**
|
||||
* Handles a flow exception that was not handled by the Web Flow system. Used by a Controller to handle a specific
|
||||
|
||||
@@ -75,8 +75,8 @@ public class FlowHandlerAdapter extends PortletApplicationObjectSupport implemen
|
||||
session.removeAttribute(FLOW_EXECUTION_RESULT_ATTRIBUTE);
|
||||
String outcome = result.getEndedOutcome();
|
||||
AttributeMap output = result.getEndedOutput();
|
||||
ModelAndView mv = flowHandler.handleFlowOutcome(outcome, output, request, response);
|
||||
return mv != null ? mv : defaultHandleFlowOutcome(flowHandler, outcome, output, request, response);
|
||||
String flowId = flowHandler.handleFlowOutcome(outcome, output, request, response);
|
||||
return defaultHandleFlowOutcome(flowHandler, outcome, output, flowId, request, response);
|
||||
} else {
|
||||
return startFlow(request, response, flowHandler);
|
||||
}
|
||||
@@ -131,14 +131,15 @@ public class FlowHandlerAdapter extends PortletApplicationObjectSupport implemen
|
||||
}
|
||||
|
||||
protected ModelAndView defaultHandleFlowOutcome(FlowHandler flowHandler, String outcome, AttributeMap output,
|
||||
RenderRequest request, RenderResponse response) throws IOException {
|
||||
// by default, just start the flow over passing the output as input
|
||||
String flowId = flowHandler.getFlowId();
|
||||
String nextFlowId, RenderRequest request, RenderResponse response) throws IOException {
|
||||
if (nextFlowId == null) {
|
||||
nextFlowId = flowHandler.getFlowId();
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Restarting a new execution of ended flow '" + flowId + "'");
|
||||
logger.debug("Starting a new execution of flow '" + nextFlowId + "'");
|
||||
}
|
||||
PortletExternalContext context = createPortletExternalContext(request, response);
|
||||
flowExecutor.launchExecution(flowId, new LocalAttributeMap(output.asMap()), context);
|
||||
flowExecutor.launchExecution(nextFlowId, new LocalAttributeMap(output.asMap()), context);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ public class AbstractFlowHandler implements FlowHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ModelAndView handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
public String handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ModelAndView handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.AbstractController;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
import org.springframework.webflow.context.servlet.DefaultFlowUrlHandler;
|
||||
import org.springframework.webflow.context.servlet.FlowUrlHandler;
|
||||
import org.springframework.webflow.context.servlet.ServletExternalContext;
|
||||
@@ -268,13 +269,18 @@ public class FlowController extends AbstractController {
|
||||
HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
FlowHandler handler = getFlowHandler(flowId);
|
||||
if (handler != null) {
|
||||
ModelAndView result = handler.handleExecutionOutcome(outcome, endedOutput, request, response);
|
||||
return result != null ? result : defaultHandleFlowOutcome(flowId, outcome, endedOutput, request, response);
|
||||
String location = handler.handleExecutionOutcome(outcome, endedOutput, request, response);
|
||||
return location != null ? createRedirectView(location) : defaultHandleFlowOutcome(flowId, outcome,
|
||||
endedOutput, request, response);
|
||||
} else {
|
||||
return defaultHandleFlowOutcome(flowId, outcome, endedOutput, request, response);
|
||||
}
|
||||
}
|
||||
|
||||
private ModelAndView createRedirectView(String location) {
|
||||
return new ModelAndView(new RedirectView(location, true));
|
||||
}
|
||||
|
||||
private ModelAndView handleFlowException(FlowException e, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException {
|
||||
String flowId = urlHandler.getFlowId(request);
|
||||
|
||||
@@ -52,15 +52,16 @@ public interface FlowHandler {
|
||||
public MutableAttributeMap createExecutionInputMap(HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* Handles a specific flow execution outcome. Used by a Controller to select a new view to render after the flow
|
||||
* ends.
|
||||
* Handles a specific flow execution outcome. Used by a Controller to get the location of the resource to redirect
|
||||
* to after the outcome is handled.
|
||||
* @param outcome the outcome that was reached
|
||||
* @param output the output returned by the flow execution
|
||||
* @param request the current request
|
||||
* @param response the current response
|
||||
* @return the model and view to render on the occurrence of this outcome, or null if the outcome was not handled
|
||||
* @return the location of the new resource to redirect to, or null if the execution outcome was not handled and
|
||||
* should be handled by the caller
|
||||
*/
|
||||
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
public String handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
HttpServletResponse response);
|
||||
|
||||
/**
|
||||
@@ -70,7 +71,8 @@ public interface FlowHandler {
|
||||
* the flow executor system if no execution could be restored.
|
||||
* @param request the current request
|
||||
* @param response the current response
|
||||
* @return the model and view to render on the occurrence of this exception, or null if the exception is not handled
|
||||
* @return the model and view to render on the occurrence of this exception, or null if the exception was not
|
||||
* handled and should be handled by the caller
|
||||
*/
|
||||
public ModelAndView handleException(FlowException e, HttpServletRequest request, HttpServletResponse response);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.web.context.support.WebApplicationObjectSupport;
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.view.RedirectView;
|
||||
import org.springframework.webflow.context.servlet.DefaultFlowUrlHandler;
|
||||
import org.springframework.webflow.context.servlet.FlowUrlHandler;
|
||||
import org.springframework.webflow.context.servlet.ServletExternalContext;
|
||||
@@ -224,16 +225,20 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H
|
||||
sendRedirect(context, request, response, context.getExternalRedirectUrl());
|
||||
return null;
|
||||
} else {
|
||||
ModelAndView mv = handler.handleExecutionOutcome(result.getEndedOutcome(), result.getEndedOutput(),
|
||||
String location = handler.handleExecutionOutcome(result.getEndedOutcome(), result.getEndedOutput(),
|
||||
request, response);
|
||||
return mv != null ? mv : defaultHandleFlowOutcome(result.getFlowId(), result.getEndedOutcome(), result
|
||||
.getEndedOutput(), request, response);
|
||||
return location != null ? createRedirectView(location) : defaultHandleFlowOutcome(result.getFlowId(),
|
||||
result.getEndedOutcome(), result.getEndedOutput(), request, response);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Execution result should have been one of [paused] or [ended]");
|
||||
}
|
||||
}
|
||||
|
||||
private ModelAndView createRedirectView(String location) {
|
||||
return new ModelAndView(new RedirectView(location, true));
|
||||
}
|
||||
|
||||
private void sendRedirect(ServletExternalContext context, HttpServletRequest request, HttpServletResponse response,
|
||||
String targetUrl) throws IOException {
|
||||
if (context.isAjaxRequest()) {
|
||||
|
||||
@@ -133,7 +133,7 @@ public class MockExternalContext implements ExternalContext {
|
||||
return ajaxRequest;
|
||||
}
|
||||
|
||||
public String getFlowExecutionUri(String flowId, String flowExecutionKey) {
|
||||
public String getFlowExecutionUrl(String flowId, String flowExecutionKey) {
|
||||
return "/" + flowId + "?execution=" + flowExecutionKey;
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ public class MockRequestContext implements RequestContext {
|
||||
"Flow execution key not yet assigned; unable to build the flow execution url");
|
||||
} else {
|
||||
String flowDefinitionId = flowExecutionContext.getDefinition().getId();
|
||||
return externalContext.getFlowExecutionUri(flowDefinitionId, flowExecutionContext.getKey().toString());
|
||||
return externalContext.getFlowExecutionUrl(flowDefinitionId, flowExecutionContext.getKey().toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,10 +85,10 @@ public class FlowHandlerAdapterTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public ModelAndView handleFlowOutcome(String outcome, AttributeMap output, RenderRequest request,
|
||||
public String handleFlowOutcome(String outcome, AttributeMap output, RenderRequest request,
|
||||
RenderResponse response) {
|
||||
if (handleExecutionOutcome) {
|
||||
return new ModelAndView("redirect:/home");
|
||||
return "home";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@@ -172,16 +172,19 @@ public class FlowHandlerAdapterTests extends TestCase {
|
||||
public void testHandleFlowOutcomeCustomFlowHandler() throws Exception {
|
||||
handleExecutionOutcome = true;
|
||||
renderRequest.setContextPath("/springtravel");
|
||||
executor.launchExecution("foo", flowInput, renderContext);
|
||||
LocalAttributeMap output = new LocalAttributeMap();
|
||||
output.put("bar", "baz");
|
||||
Event outcome = new Event(this, "finish", output);
|
||||
FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome);
|
||||
PortletSession session = renderRequest.getPortletSession();
|
||||
session.setAttribute("flowExecutionResult", result);
|
||||
executor.launchExecution("home", flowInput, renderContext);
|
||||
EasyMock.expectLastCall().andReturn(FlowExecutionResult.createEndedResult("bar", outcome));
|
||||
EasyMock.replay(new Object[] { executor });
|
||||
ModelAndView mv = controller.handleRender(renderRequest, renderResponse, flowHandler);
|
||||
assertNotNull(mv);
|
||||
assertEquals("redirect:/home", mv.getViewName());
|
||||
assertNull(mv);
|
||||
EasyMock.verify(new Object[] { executor });
|
||||
|
||||
}
|
||||
|
||||
public void testHandleFlowExceptionCustomFlowHandler() throws Exception {
|
||||
|
||||
@@ -23,8 +23,6 @@ import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.repository.NoSuchFlowExecutionException;
|
||||
import org.springframework.webflow.executor.FlowExecutionResult;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
import org.springframework.webflow.mvc.servlet.FlowController;
|
||||
import org.springframework.webflow.mvc.servlet.FlowHandler;
|
||||
import org.springframework.webflow.test.MockFlowExecutionKey;
|
||||
|
||||
public class FlowControllerTests extends TestCase {
|
||||
@@ -291,7 +289,7 @@ public class FlowControllerTests extends TestCase {
|
||||
return input;
|
||||
}
|
||||
|
||||
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
public String handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return null;
|
||||
}
|
||||
@@ -327,7 +325,7 @@ public class FlowControllerTests extends TestCase {
|
||||
return input;
|
||||
}
|
||||
|
||||
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
public String handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
assertEquals("finish", outcome);
|
||||
assertEquals("baz", output.get("bar"));
|
||||
@@ -372,7 +370,7 @@ public class FlowControllerTests extends TestCase {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
public String handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ import org.springframework.webflow.execution.Event;
|
||||
import org.springframework.webflow.execution.repository.NoSuchFlowExecutionException;
|
||||
import org.springframework.webflow.executor.FlowExecutionResult;
|
||||
import org.springframework.webflow.executor.FlowExecutor;
|
||||
import org.springframework.webflow.mvc.servlet.FlowHandler;
|
||||
import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter;
|
||||
import org.springframework.webflow.test.MockFlowExecutionKey;
|
||||
|
||||
public class FlowHandlerAdapterTests extends TestCase {
|
||||
@@ -72,10 +70,10 @@ public class FlowHandlerAdapterTests extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public ModelAndView handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
public String handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
if (handleExecutionOutcome) {
|
||||
return new ModelAndView("redirect:/home");
|
||||
return "/home";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user