diff --git a/spring-webflow/src/main/java/org/springframework/webflow/context/ExternalContext.java b/spring-webflow/src/main/java/org/springframework/webflow/context/ExternalContext.java index af3c9137..6c8a6406 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/context/ExternalContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/context/ExternalContext.java @@ -19,7 +19,6 @@ import java.io.Writer; import java.security.Principal; import java.util.Locale; -import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.MutableAttributeMap; import org.springframework.webflow.core.collection.ParameterMap; import org.springframework.webflow.core.collection.SharedAttributeMap; @@ -154,21 +153,21 @@ public interface ExternalContext { * @param flowId the id of the flow definition to redirect to * @param input input to pass the flow; this input is generally encoded the url to launch the flow */ - public void requestFlowDefinitionRedirect(String flowId, AttributeMap input); + public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input); /** - * Request a redirect to an arbitrary resource URI. May not be supported in some environments. Calling this method - * commits the response. + * Request a redirect to an arbitrary resource location. May not be supported in some environments. Calling this + * method commits the response. * @see #isResponseCommitted() - * @param uri the URI to redirect to + * @param location the location of the resource to redirect to */ - public void requestExternalRedirect(String uri); + public void requestExternalRedirect(String location); /** * Request that the redirect response requested be sent to the client in a manner that causes the client to issue * the redirect from a popup dialog. Calling this method only has an effect when a redirect has been requested. * @see #requestFlowExecutionRedirect() - * @see #requestFlowDefinitionRedirect(String, AttributeMap) + * @see #requestFlowDefinitionRedirect(String, MutableAttributeMap) * @see #requestExternalRedirect(String) */ public void requestRedirectInPopup(); diff --git a/spring-webflow/src/main/java/org/springframework/webflow/context/portlet/PortletExternalContext.java b/spring-webflow/src/main/java/org/springframework/webflow/context/portlet/PortletExternalContext.java index 5b39575c..e1b641a9 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/context/portlet/PortletExternalContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/context/portlet/PortletExternalContext.java @@ -29,7 +29,6 @@ import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import org.springframework.webflow.context.ExternalContext; -import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.LocalAttributeMap; import org.springframework.webflow.core.collection.LocalParameterMap; import org.springframework.webflow.core.collection.LocalSharedAttributeMap; @@ -106,7 +105,7 @@ public class PortletExternalContext implements ExternalContext { * Input to pass the flow definition upon redirecting. May be null. Never set unless * {@link #flowDefinitionRedirectFlowId} has been set. */ - private AttributeMap flowDefinitionRedirectFlowInput; + private MutableAttributeMap flowDefinitionRedirectFlowInput; /** * A string specifying an arbitrary @@ -233,7 +232,7 @@ public class PortletExternalContext implements ExternalContext { externalRedirectUrl = uri; } - public void requestFlowDefinitionRedirect(String flowId, AttributeMap input) { + public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input) { flowDefinitionRedirectFlowId = flowId; flowDefinitionRedirectFlowInput = input; } @@ -270,7 +269,7 @@ public class PortletExternalContext implements ExternalContext { * Returns the input to pass the flow definition through the redirect. Only set when * {@link #getFlowDefinitionRedirectRequested()} returns true. */ - public AttributeMap getFlowRedirectFlowInput() { + public MutableAttributeMap getFlowRedirectFlowInput() { return flowDefinitionRedirectFlowInput; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/ServletExternalContext.java b/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/ServletExternalContext.java index bdeee49d..b0aebb45 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/ServletExternalContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/context/servlet/ServletExternalContext.java @@ -25,7 +25,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.webflow.context.ExternalContext; -import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.LocalAttributeMap; import org.springframework.webflow.core.collection.LocalParameterMap; import org.springframework.webflow.core.collection.LocalSharedAttributeMap; @@ -92,7 +91,7 @@ public class ServletExternalContext implements ExternalContext { * Input to pass the flow definition upon redirecting. May be null. Never set unless * {@link #flowDefinitionRedirectFlowId} has been set. */ - private AttributeMap flowDefinitionRedirectFlowInput; + private MutableAttributeMap flowDefinitionRedirectFlowInput; /** * A string specifying an arbitrary @@ -221,11 +220,11 @@ public class ServletExternalContext implements ExternalContext { flowExecutionRedirectRequested = true; } - public void requestExternalRedirect(String uri) { - externalRedirectUrl = uri; + public void requestExternalRedirect(String location) { + externalRedirectUrl = location; } - public void requestFlowDefinitionRedirect(String flowId, AttributeMap input) { + public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input) { flowDefinitionRedirectFlowId = flowId; flowDefinitionRedirectFlowInput = input; } @@ -262,7 +261,7 @@ public class ServletExternalContext implements ExternalContext { * Returns the input to pass the flow definition through the redirect. Only set when * {@link #getFlowDefinitionRedirectRequested()} returns true. */ - public AttributeMap getFlowRedirectFlowInput() { + public MutableAttributeMap getFlowRedirectFlowInput() { return flowDefinitionRedirectFlowInput; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandler.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandler.java index fcc020b7..2fba7a79 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandler.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandler.java @@ -56,15 +56,15 @@ public interface FlowHandler { *

* The following prefixes are supported for qualifying the returned location string: *

* Also, if the returned location no prefix, for example "/hotels/index", the location is treated as relative to the - * current servlet by default + * current servlet by default. *

- * For servlet-relative and context-relative URLs, a leading slash is optional. + * For servlet-relative, context-relative, and server-relative URLs, a leading slash is optional. * * @param outcome the outcome that was reached * @param request the current request diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapter.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapter.java index 96f7fe3b..9b63fef6 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapter.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapter.java @@ -16,6 +16,8 @@ package org.springframework.webflow.mvc.servlet; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; import java.util.Iterator; import java.util.Map; @@ -31,12 +33,10 @@ import org.springframework.util.Assert; 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; import org.springframework.webflow.core.FlowException; -import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.LocalAttributeMap; import org.springframework.webflow.core.collection.MutableAttributeMap; import org.springframework.webflow.execution.FlowExecutionOutcome; @@ -54,11 +54,13 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H private static final Log logger = LogFactory.getLog(FlowHandlerAdapter.class); - private static final String SERVLET_PATH_LOCATION_PREFIX = "servletPath:"; + private static final String SERVLET_RELATIVE_LOCATION_PREFIX = "servletRelative:"; - private static final String CONTEXT_PATH_LOCATION_PREFIX = "contextPath:"; + private static final String CONTEXT_RELATIVE_LOCATION_PREFIX = "contextRelative:"; - private static final String REDIRECT_URL_LOCATION_PREFIX = "redirectUrl:"; + private static final String SERVER_RELATIVE_LOCATION_PREFIX = "serverRelative:"; + + private static final String URL_LOCATION_PREFIX = "url:"; /** * The entry point into Spring Web Flow. @@ -152,9 +154,9 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H try { ServletExternalContext context = createServletExternalContext(request, response); FlowExecutionResult result = flowExecutor.resumeExecution(flowExecutionKey, context); - return handleFlowExecutionResult(result, context, request, response, flowHandler); + handleFlowExecutionResult(result, context, request, response, flowHandler); } catch (FlowException e) { - return handleFlowException(e, request, response, flowHandler); + handleFlowException(e, request, response, flowHandler); } } else { try { @@ -162,11 +164,12 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H MutableAttributeMap input = getInputMap(flowHandler, request); ServletExternalContext context = createServletExternalContext(request, response); FlowExecutionResult result = flowExecutor.launchExecution(flowId, input, context); - return handleFlowExecutionResult(result, context, request, response, flowHandler); + handleFlowExecutionResult(result, context, request, response, flowHandler); } catch (FlowException e) { - return handleFlowException(e, request, response, flowHandler); + handleFlowException(e, request, response, flowHandler); } } + return null; } // subclassing hooks @@ -229,7 +232,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H * @param request the current request * @param response the current response */ - protected ModelAndView defaultHandleExecutionOutcome(String flowId, FlowExecutionOutcome outcome, + protected void defaultHandleExecutionOutcome(String flowId, FlowExecutionOutcome outcome, HttpServletRequest request, HttpServletResponse response) throws IOException { if (!response.isCommitted()) { // by default, just start the flow over passing the output as input @@ -238,7 +241,6 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H } response.sendRedirect(urlHandler.createFlowDefinitionUrl(flowId, outcome.getOutput(), request)); } - return null; } /** @@ -251,7 +253,7 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H * @param request the current request * @param response the current response */ - protected ModelAndView defaultHandleException(String flowId, FlowException e, HttpServletRequest request, + protected void defaultHandleException(String flowId, FlowException e, HttpServletRequest request, HttpServletResponse response) throws IOException { if (e instanceof NoSuchFlowExecutionException && flowId != null) { if (!response.isCommitted()) { @@ -261,7 +263,6 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H // by default, attempt to restart the flow response.sendRedirect(urlHandler.createFlowDefinitionUrl(flowId, null, request)); } - return null; } else { throw e; } @@ -269,91 +270,122 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H // internal helpers - private ModelAndView handleFlowExecutionResult(FlowExecutionResult result, ServletExternalContext context, + private void handleFlowExecutionResult(FlowExecutionResult result, ServletExternalContext context, HttpServletRequest request, HttpServletResponse response, FlowHandler handler) throws IOException { if (result.isPaused()) { if (context.getFlowExecutionRedirectRequested()) { - String url = urlHandler.createFlowExecutionUrl(result.getFlowId(), result.getPausedKey(), request); - if (logger.isDebugEnabled()) { - logger.debug("Sending flow execution redirect to " + url); - } - sendRedirect(context, request, response, url); - return null; + sendFlowExecutionRedirect(result, context, request, response); + } else if (context.getFlowDefinitionRedirectRequested()) { + sendFlowDefinitionRedirect(result, context, request, response); } else if (context.getExternalRedirectRequested()) { - if (logger.isDebugEnabled()) { - logger.debug("Sending external redirect to " + context.getExternalRedirectUrl()); - } - sendRedirect(context, request, response, context.getExternalRedirectUrl()); - return null; - } else { - return null; + sendExternalRedirect(context.getExternalRedirectUrl(), request, response); } } else if (result.isEnded()) { if (context.getFlowDefinitionRedirectRequested()) { - String flowId = context.getFlowRedirectFlowId(); - AttributeMap input = context.getFlowRedirectFlowInput(); - String url = urlHandler.createFlowDefinitionUrl(flowId, input, request); - if (logger.isDebugEnabled()) { - logger.debug("Sending flow definition to " + url); - } - sendRedirect(context, request, response, url); - return null; + sendFlowDefinitionRedirect(result, context, request, response); } else if (context.getExternalRedirectRequested()) { - if (logger.isDebugEnabled()) { - logger.debug("Sending external redirect to " + context.getExternalRedirectUrl()); - } - sendRedirect(context, request, response, context.getExternalRedirectUrl()); - return null; + sendExternalRedirect(context.getExternalRedirectUrl(), request, response); } else { String location = handler.handleExecutionOutcome(result.getOutcome(), request, response); - return location != null ? createRedirectView(location, request) : defaultHandleExecutionOutcome(result - .getFlowId(), result.getOutcome(), request, response); + if (location != null) { + sendExternalRedirect(location, request, response); + } else { + defaultHandleExecutionOutcome(result.getFlowId(), result.getOutcome(), request, response); + } } } else { throw new IllegalStateException("Execution result should have been one of [paused] or [ended]"); } } - private ModelAndView createRedirectView(String location, HttpServletRequest request) { - if (location.startsWith(SERVLET_PATH_LOCATION_PREFIX)) { - return createServletRelativeRedirect(location.substring(SERVLET_PATH_LOCATION_PREFIX.length()), request); - } else if (location.startsWith(CONTEXT_PATH_LOCATION_PREFIX)) { - String contextUrl = location.substring(CONTEXT_PATH_LOCATION_PREFIX.length()); - if (!contextUrl.startsWith("/")) { - contextUrl = "/" + contextUrl; - } - return new ModelAndView(new RedirectView(contextUrl, true)); - } else if (location.startsWith(REDIRECT_URL_LOCATION_PREFIX)) { - return new ModelAndView(new RedirectView(location.substring(REDIRECT_URL_LOCATION_PREFIX.length()))); + private void sendFlowExecutionRedirect(FlowExecutionResult result, ServletExternalContext context, + HttpServletRequest request, HttpServletResponse response) throws IOException { + String url = urlHandler.createFlowExecutionUrl(result.getFlowId(), result.getPausedKey(), request); + if (logger.isDebugEnabled()) { + logger.debug("Sending flow execution redirect to '" + url + "'"); + } + if (context.isAjaxRequest()) { + ajaxHandler.sendAjaxRedirect(getServletContext(), request, response, url, context.getRedirectInPopup()); } else { - return createServletRelativeRedirect(location, request); + sendRedirect(url, response); } } - private ModelAndView createServletRelativeRedirect(String location, HttpServletRequest request) { + private void sendFlowDefinitionRedirect(FlowExecutionResult result, ServletExternalContext context, + HttpServletRequest request, HttpServletResponse response) throws IOException { + String flowId = context.getFlowRedirectFlowId(); + MutableAttributeMap input = context.getFlowRedirectFlowInput(); + if (result.isPaused()) { + input.put("refererExecution", result.getPausedKey()); + } + String url = urlHandler.createFlowDefinitionUrl(flowId, input, request); + if (logger.isDebugEnabled()) { + logger.debug("Sending flow definition redirect to '" + url + "'"); + } + sendRedirect(url, response); + } + + private void sendExternalRedirect(String location, HttpServletRequest request, HttpServletResponse response) + throws IOException { + if (logger.isDebugEnabled()) { + logger.debug("Sending external redirect to '" + location + "'"); + } + if (location.startsWith(SERVLET_RELATIVE_LOCATION_PREFIX)) { + sendServletRelativeRedirect(location.substring(SERVLET_RELATIVE_LOCATION_PREFIX.length()), request, + response); + } else if (location.startsWith(CONTEXT_RELATIVE_LOCATION_PREFIX)) { + StringBuffer url = new StringBuffer(request.getContextPath()); + String contextRelativeUrl = location.substring(CONTEXT_RELATIVE_LOCATION_PREFIX.length()); + if (!contextRelativeUrl.startsWith("/")) { + url.append('/'); + } + url.append(contextRelativeUrl); + sendRedirect(url.toString(), response); + } else if (location.startsWith(SERVER_RELATIVE_LOCATION_PREFIX)) { + String url = location.substring(SERVER_RELATIVE_LOCATION_PREFIX.length()); + if (!url.startsWith("/")) { + url = "/" + url; + } + sendRedirect(url, response); + } else if (location.startsWith(URL_LOCATION_PREFIX)) { + String url = location.substring(URL_LOCATION_PREFIX.length()); + try { + new URL(url); + sendRedirect(url, response); + } catch (MalformedURLException e) { + IllegalArgumentException iae = new IllegalArgumentException("The redirect url '" + url + + "' is invalid; specify a fully qualified URL when using the '" + URL_LOCATION_PREFIX + + "' location prefix"); + e.initCause(e); + throw iae; + } + } else { + sendServletRelativeRedirect(location, request, response); + } + } + + private void sendServletRelativeRedirect(String location, HttpServletRequest request, HttpServletResponse response) + throws IOException { StringBuffer url = new StringBuffer(request.getServletPath()); if (!location.startsWith("/")) { url.append('/'); } url.append(location); - return new ModelAndView(new RedirectView(url.toString(), true)); + sendRedirect(url.toString(), response); } - private void sendRedirect(ServletExternalContext context, HttpServletRequest request, HttpServletResponse response, - String targetUrl) throws IOException { - if (context.isAjaxRequest()) { - ajaxHandler.sendAjaxRedirect(getServletContext(), request, response, targetUrl, context - .getRedirectInPopup()); - } else if (!response.isCommitted()) { - response.sendRedirect(response.encodeRedirectURL(targetUrl)); - } + private void sendRedirect(String url, HttpServletResponse response) throws IOException { + response.sendRedirect(response.encodeRedirectURL(url)); } - private ModelAndView handleFlowException(FlowException e, HttpServletRequest request, HttpServletResponse response, + private void handleFlowException(FlowException e, HttpServletRequest request, HttpServletResponse response, FlowHandler handler) throws IOException { String location = handler.handleException(e, request, response); - return location != null ? createRedirectView(location, request) : defaultHandleException(getFlowId(handler, - request), e, request, response); + if (location != null) { + sendExternalRedirect(location, request, response); + } else { + defaultHandleException(getFlowId(handler, request), e, request, response); + } } public long getLastModified(HttpServletRequest request, Object handler) { diff --git a/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java b/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java index 055825ba..19dfa22e 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/test/MockExternalContext.java @@ -23,7 +23,6 @@ import java.util.Locale; import org.springframework.binding.collection.SharedMapDecorator; import org.springframework.webflow.context.ExternalContext; -import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.LocalAttributeMap; import org.springframework.webflow.core.collection.LocalSharedAttributeMap; import org.springframework.webflow.core.collection.MutableAttributeMap; @@ -67,7 +66,7 @@ public class MockExternalContext implements ExternalContext { private String flowDefinitionRedirectFlowId; - private AttributeMap flowDefinitionRedirectFlowInput; + private MutableAttributeMap flowDefinitionRedirectFlowInput; private String externalRedirectUrl; @@ -161,7 +160,7 @@ public class MockExternalContext implements ExternalContext { flowExecutionRedirectRequested = true; } - public void requestFlowDefinitionRedirect(String flowId, AttributeMap input) { + public void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap input) { flowDefinitionRedirectFlowId = flowId; flowDefinitionRedirectFlowInput = input; } @@ -342,7 +341,7 @@ public class MockExternalContext implements ExternalContext { * Returns the input to pass the flow definition through the redirect. Only set when * {@link #getFlowDefinitionRedirectRequested()} returns true. */ - public AttributeMap getFlowRedirectFlowInput() { + public MutableAttributeMap getFlowRedirectFlowInput() { return flowDefinitionRedirectFlowInput; } diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/FlowControllerTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/FlowControllerTests.java index a43b55f9..84230a46 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/FlowControllerTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/FlowControllerTests.java @@ -224,7 +224,7 @@ public class FlowControllerTests extends TestCase { request.setPathInfo("/foo"); request.setRequestURI("/springtravel/app/foo"); request.setMethod("GET"); - context.requestExternalRedirect("http://www.paypal.com"); + context.requestExternalRedirect("url:http://www.paypal.com"); executor.launchExecution("foo", null, context); FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345"); EasyMock.expectLastCall().andReturn(result); diff --git a/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapterTests.java b/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapterTests.java index a883cc56..c5579e37 100644 --- a/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapterTests.java +++ b/spring-webflow/src/test/java/org/springframework/webflow/mvc/servlet/FlowHandlerAdapterTests.java @@ -93,8 +93,7 @@ public class FlowHandlerAdapterTests extends TestCase { FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345"); EasyMock.expectLastCall().andReturn(result); EasyMock.replay(new Object[] { flowExecutor }); - ModelAndView mv = flowHandlerAdapter.handle(request, response, flowHandler); - assertNull(mv); + flowHandlerAdapter.handle(request, response, flowHandler); EasyMock.verify(new Object[] { flowExecutor }); } @@ -113,8 +112,7 @@ public class FlowHandlerAdapterTests extends TestCase { FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome); EasyMock.expectLastCall().andReturn(result); EasyMock.replay(new Object[] { flowExecutor }); - ModelAndView mv = flowHandlerAdapter.handle(request, response, flowHandler); - assertNull(mv); + flowHandlerAdapter.handle(request, response, flowHandler); assertEquals("/springtravel/app/foo?bar=baz", response.getRedirectedUrl()); EasyMock.verify(new Object[] { flowExecutor }); } @@ -130,8 +128,7 @@ public class FlowHandlerAdapterTests extends TestCase { FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "123456"); EasyMock.expectLastCall().andReturn(result); EasyMock.replay(new Object[] { flowExecutor }); - ModelAndView mv = flowHandlerAdapter.handle(request, response, flowHandler); - assertNull(mv); + flowHandlerAdapter.handle(request, response, flowHandler); EasyMock.verify(new Object[] { flowExecutor }); } @@ -168,8 +165,7 @@ public class FlowHandlerAdapterTests extends TestCase { FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345"); EasyMock.expectLastCall().andReturn(result); EasyMock.replay(new Object[] { flowExecutor }); - ModelAndView mv = flowHandlerAdapter.handle(request, response, flowHandler); - assertNull(mv); + flowHandlerAdapter.handle(request, response, flowHandler); EasyMock.verify(new Object[] { flowExecutor }); assertEquals("/springtravel/app/foo?execution=12345", response.getRedirectedUrl()); EasyMock.verify(new Object[] { flowExecutor }); @@ -206,13 +202,12 @@ public class FlowHandlerAdapterTests extends TestCase { request.setPathInfo("/foo"); request.setRequestURI("/springtravel/app/foo"); request.setMethod("GET"); - context.requestExternalRedirect("http://www.paypal.com"); + context.requestExternalRedirect("url:http://www.paypal.com"); flowExecutor.launchExecution("foo", flowInput, context); FlowExecutionResult result = FlowExecutionResult.createPausedResult("foo", "12345"); EasyMock.expectLastCall().andReturn(result); EasyMock.replay(new Object[] { flowExecutor }); - ModelAndView mv = flowHandlerAdapter.handle(request, response, flowHandler); - assertNull(mv); + flowHandlerAdapter.handle(request, response, flowHandler); EasyMock.verify(new Object[] { flowExecutor }); assertEquals("http://www.paypal.com", response.getRedirectedUrl()); EasyMock.verify(new Object[] { flowExecutor }); @@ -251,8 +246,7 @@ public class FlowHandlerAdapterTests extends TestCase { FlowException flowException = new NoSuchFlowExecutionException(new MockFlowExecutionKey("12345"), null); EasyMock.expectLastCall().andThrow(flowException); EasyMock.replay(new Object[] { flowExecutor }); - ModelAndView mv = flowHandlerAdapter.handle(request, response, flowHandler); - assertNull(mv); + flowHandlerAdapter.handle(request, response, flowHandler); assertEquals("/springtravel/app/foo", response.getRedirectedUrl()); EasyMock.verify(new Object[] { flowExecutor }); } @@ -271,8 +265,7 @@ public class FlowHandlerAdapterTests extends TestCase { FlowExecutionResult result = FlowExecutionResult.createEndedResult("foo", outcome); EasyMock.expectLastCall().andReturn(result); EasyMock.replay(new Object[] { flowExecutor }); - ModelAndView mv = flowHandlerAdapter.handle(request, response, flowHandler); - assertNotNull(mv); + flowHandlerAdapter.handle(request, response, flowHandler); EasyMock.verify(new Object[] { flowExecutor }); } @@ -288,8 +281,7 @@ public class FlowHandlerAdapterTests extends TestCase { flowExecutor.launchExecution("foo", flowInput, context); EasyMock.expectLastCall().andThrow(flowException); EasyMock.replay(new Object[] { flowExecutor }); - ModelAndView mv = flowHandlerAdapter.handle(request, response, flowHandler); - assertNotNull(mv); + flowHandlerAdapter.handle(request, response, flowHandler); EasyMock.verify(new Object[] { flowExecutor }); } }