diff --git a/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingFlowHandler.java b/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingFlowHandler.java index ff699ef9..0344b324 100644 --- a/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingFlowHandler.java +++ b/spring-webflow-samples/booking-mvc/src/main/java/org/springframework/webflow/samples/booking/BookingFlowHandler.java @@ -3,9 +3,9 @@ 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.webflow.core.FlowException; import org.springframework.webflow.core.collection.AttributeMap; +import org.springframework.webflow.execution.repository.NoSuchFlowExecutionException; import org.springframework.webflow.mvc.servlet.AbstractFlowHandler; public class BookingFlowHandler extends AbstractFlowHandler { @@ -15,8 +15,12 @@ public class BookingFlowHandler extends AbstractFlowHandler { } @Override - public ModelAndView handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) { - return new ModelAndView("redirect:/spring/hotels/index"); + public String handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) { + if (e instanceof NoSuchFlowExecutionException) { + return "hotels/index"; + } else { + throw e; + } } } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/FlowExecutionImpl.java b/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/FlowExecutionImpl.java index d50994d5..f8577f2d 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/FlowExecutionImpl.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/engine/impl/FlowExecutionImpl.java @@ -589,7 +589,12 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable { throws FlowExecutionException { listeners.fireExceptionThrown(context, exception); if (logger.isDebugEnabled()) { - logger.debug("Attempting to handle [" + exception + "]"); + if (exception.getCause() != null) { + logger.debug("Attempting to handle [" + exception + "] with root cause [" + getRootCause(exception) + + "]"); + } else { + logger.debug("Attempting to handle [" + exception + "]"); + } } boolean handled = false; try { @@ -608,6 +613,14 @@ public class FlowExecutionImpl implements FlowExecution, Externalizable { } } + /** + * Get the root cause of the given throwable. + */ + private Throwable getRootCause(Throwable e) { + Throwable cause = e.getCause(); + return cause == null ? e : getRootCause(cause); + } + /** * Try to handle given exception using execution exception handlers registered at the state level. Returns null if * no handler handled the exception. diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/AbstractFlowHandler.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/AbstractFlowHandler.java index 7df43d4d..5ab1bf82 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/AbstractFlowHandler.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/AbstractFlowHandler.java @@ -3,7 +3,6 @@ package org.springframework.webflow.mvc.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.springframework.web.servlet.ModelAndView; import org.springframework.webflow.core.FlowException; import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.MutableAttributeMap; @@ -29,7 +28,7 @@ public class AbstractFlowHandler implements FlowHandler { return null; } - public ModelAndView handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) { + public String handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) { return null; } diff --git a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowController.java b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowController.java index 24cc3124..4cc5e671 100644 --- a/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowController.java +++ b/spring-webflow/src/main/java/org/springframework/webflow/mvc/servlet/FlowController.java @@ -324,8 +324,9 @@ public class FlowController extends AbstractController { if (flowId != null) { FlowHandler handler = getFlowHandler(flowId); if (handler != null) { - ModelAndView result = handler.handleException(e, request, response); - return result != null ? result : defaultHandleFlowException(flowId, e, request, response); + String location = handler.handleException(e, request, response); + return location != null ? createRedirectView(location, request) : defaultHandleFlowException(flowId, e, + request, response); } else { return defaultHandleFlowException(flowId, e, request, response); } 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 3c810916..ebb5da76 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 @@ -18,7 +18,6 @@ package org.springframework.webflow.mvc.servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.springframework.web.servlet.ModelAndView; import org.springframework.webflow.core.FlowException; import org.springframework.webflow.core.collection.AttributeMap; import org.springframework.webflow.core.collection.MutableAttributeMap; @@ -76,8 +75,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 was not - * handled and should be handled by the caller + * @return the location of the error resource to redirect to, or null if the execution outcome was not handled and + * should be handled by the caller */ - public ModelAndView handleException(FlowException e, HttpServletRequest request, HttpServletResponse response); + public String handleException(FlowException e, HttpServletRequest request, HttpServletResponse response); } 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 b9a788f6..1a90a9d4 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 @@ -257,8 +257,9 @@ public class FlowHandlerAdapter extends WebApplicationObjectSupport implements H private ModelAndView handleFlowException(FlowException e, HttpServletRequest request, HttpServletResponse response, FlowHandler handler) throws IOException { - ModelAndView result = handler.handleException(e, request, response); - return result != null ? result : defaultHandleFlowException(getFlowId(handler, request), e, request, response); + String location = handler.handleException(e, request, response); + return location != null ? createRedirectView(location, request) : defaultHandleFlowException(getFlowId(handler, + request), e, request, response); } public long getLastModified(HttpServletRequest request, Object handler) { 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 ca615bc3..4f46e0ad 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 @@ -294,8 +294,7 @@ public class FlowControllerTests extends TestCase { return null; } - public ModelAndView handleException(FlowException e, HttpServletRequest request, - HttpServletResponse response) { + public String handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) { return null; } }); @@ -334,8 +333,7 @@ public class FlowControllerTests extends TestCase { return null; } - public ModelAndView handleException(FlowException e, HttpServletRequest request, - HttpServletResponse response) { + public String handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) { return null; } }); @@ -375,8 +373,7 @@ public class FlowControllerTests extends TestCase { return null; } - public ModelAndView handleException(FlowException e, HttpServletRequest request, - HttpServletResponse response) { + public String handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) { assertEquals(flowException, e); return null; } 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 20a23fb0..575ba092 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 @@ -61,19 +61,18 @@ public class FlowHandlerAdapterTests extends TestCase { return "foo"; } - public ModelAndView handleException(FlowException e, HttpServletRequest request, + public String handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request, HttpServletResponse response) { - if (handleException) { - return new ModelAndView("error"); + if (handleExecutionOutcome) { + return "/home"; } else { return null; } } - public String handleExecutionOutcome(String outcome, AttributeMap output, HttpServletRequest request, - HttpServletResponse response) { - if (handleExecutionOutcome) { - return "/home"; + public String handleException(FlowException e, HttpServletRequest request, HttpServletResponse response) { + if (handleException) { + return "error"; } else { return null; }