now redirecting after post that generated bind/validation errors if redirectOnPause=true; consistent with redirect behavior if a transition executes but does not change state

This commit is contained in:
Keith Donald
2009-04-07 20:24:14 +00:00
parent 1af61c8e93
commit 0570108b8c
4 changed files with 83 additions and 6 deletions

View File

@@ -104,7 +104,7 @@ public class JsfView implements View {
}
/*
* Executes postback-processing portions of the standard JSF lifecyle including APPLY_REQUEST_VALUES through
* Executes postback-processing portions of the standard JSF lifecycle including APPLY_REQUEST_VALUES through
* INVOKE_APPLICATION.
*/
public void processUserEvent() {

View File

@@ -45,6 +45,7 @@ import org.springframework.util.Assert;
import org.springframework.validation.BindingResult;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.web.util.WebUtils;
import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.ParameterMap;
import org.springframework.webflow.definition.TransitionDefinition;
@@ -215,9 +216,18 @@ public abstract class AbstractMvcView implements View {
validate(model);
}
}
if (mappingResults != null && mappingResults.hasErrorResults()) {
if (mappingResults != null && hasErrors(mappingResults)) {
requestContext.getFlashScope().put(ViewActionStateHolder.KEY,
new ViewActionStateHolder(eventId, mappingResults));
ExternalContext context = requestContext.getExternalContext();
if (!context.isAjaxRequest()) {
Boolean redirectOnPause = requestContext.getFlowExecutionContext().getAttributes().getBoolean(
"alwaysRedirectOnPause");
boolean redirectAllowed = redirectOnPause != null ? redirectOnPause.booleanValue() : false;
if (redirectAllowed) {
requestContext.getExternalContext().requestFlowExecutionRedirect();
}
}
}
}

View File

@@ -38,8 +38,6 @@ import org.springframework.webflow.execution.View;
*/
public class MockRequestControlContext extends MockRequestContext implements RequestControlContext {
private boolean alwaysRedirectOnPause;
/**
* Creates a new mock request control context.
*/
@@ -120,13 +118,15 @@ public class MockRequestControlContext extends MockRequestContext implements Req
}
public boolean getRedirectOnPause() {
return alwaysRedirectOnPause;
Boolean redirectOnPause = getMockFlowExecutionContext().getAttributes().getBoolean("alwaysRedirectOnPause");
return redirectOnPause != null ? redirectOnPause.booleanValue() : false;
}
// implementation specific accessors for testing
public void setAlwaysRedirectOnPause(boolean alwaysRedirectOnPause) {
this.alwaysRedirectOnPause = alwaysRedirectOnPause;
getMockFlowExecutionContext().getAttributeMap().put("alwaysRedirectOnPause",
Boolean.valueOf(alwaysRedirectOnPause));
}
}

View File

@@ -178,6 +178,7 @@ public class MvcViewTests extends TestCase {
view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
view.processUserEvent();
assertTrue(view.hasFlowEvent());
assertFalse(context.getFlashScope().contains(ViewActionStateHolder.KEY));
assertEquals("submit", view.getFlowEvent().getId());
assertEquals("foo", bindBean.getStringProperty());
assertEquals(new Integer(5), bindBean.getIntegerProperty());
@@ -224,8 +225,74 @@ public class MvcViewTests extends TestCase {
AbstractMvcView view = new MockMvcView(mvcView, context);
view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
context.setAlwaysRedirectOnPause(true);
view.processUserEvent();
assertFalse(view.hasFlowEvent());
assertTrue(context.getFlashScope().contains(ViewActionStateHolder.KEY));
assertTrue(context.getExternalContext().isResponseCompleteFlowExecutionRedirect());
view.render();
assertEquals(context.getFlowScope().get("bindBean"), model.get("bindBean"));
BindingModel bm = (BindingModel) model.get(BindingResult.MODEL_KEY_PREFIX + "bindBean");
assertNotNull(bm);
assertEquals("bogus 1", bm.getFieldValue("integerProperty"));
assertEquals("bogus 2", bm.getFieldValue("dateProperty"));
}
public void testResumeEventBindingErrorsNoRedirectAllowed() throws Exception {
MockRequestControlContext context = new MockRequestControlContext();
context.putRequestParameter("_eventId", "submit");
context.putRequestParameter("integerProperty", "bogus 1");
context.putRequestParameter("dateProperty", "bogus 2");
BindBean bindBean = new BindBean();
StaticExpression modelObject = new StaticExpression(bindBean);
modelObject.setExpressionString("bindBean");
context.getCurrentState().getAttributes().put("model", modelObject);
context.getFlowScope().put("bindBean", bindBean);
context.getMockExternalContext().setNativeContext(new MockServletContext());
context.getMockExternalContext().setNativeRequest(new MockHttpServletRequest());
context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse());
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
view.processUserEvent();
assertTrue(context.getFlashScope().contains(ViewActionStateHolder.KEY));
assertFalse(view.hasFlowEvent());
assertFalse(context.getExternalContext().isResponseComplete());
assertFalse(context.getExternalContext().isResponseCompleteFlowExecutionRedirect());
view.render();
assertEquals(context.getFlowScope().get("bindBean"), model.get("bindBean"));
BindingModel bm = (BindingModel) model.get(BindingResult.MODEL_KEY_PREFIX + "bindBean");
assertNotNull(bm);
assertEquals("bogus 1", bm.getFieldValue("integerProperty"));
assertEquals("bogus 2", bm.getFieldValue("dateProperty"));
}
public void testResumeEventBindingErrorsNoRedirectAjaxRequest() throws Exception {
MockRequestControlContext context = new MockRequestControlContext();
context.putRequestParameter("_eventId", "submit");
context.putRequestParameter("integerProperty", "bogus 1");
context.putRequestParameter("dateProperty", "bogus 2");
BindBean bindBean = new BindBean();
StaticExpression modelObject = new StaticExpression(bindBean);
modelObject.setExpressionString("bindBean");
context.getCurrentState().getAttributes().put("model", modelObject);
context.getFlowScope().put("bindBean", bindBean);
context.getMockExternalContext().setNativeContext(new MockServletContext());
context.getMockExternalContext().setNativeRequest(new MockHttpServletRequest());
context.getMockExternalContext().setNativeResponse(new MockHttpServletResponse());
context.getMockFlowExecutionContext().setKey(new MockFlowExecutionKey("c1v1"));
org.springframework.web.servlet.View mvcView = new MockView();
AbstractMvcView view = new MockMvcView(mvcView, context);
view.setExpressionParser(DefaultExpressionParserFactory.getExpressionParser());
view.setMessageCodesResolver(new WebFlowMessageCodesResolver());
context.getMockExternalContext().setAjaxRequest(true);
view.processUserEvent();
assertFalse(view.hasFlowEvent());
assertFalse(context.getExternalContext().isResponseComplete());
assertFalse(context.getExternalContext().isResponseCompleteFlowExecutionRedirect());
assertTrue(context.getFlashScope().contains(ViewActionStateHolder.KEY));
view.render();
assertEquals(context.getFlowScope().get("bindBean"), model.get("bindBean"));
BindingModel bm = (BindingModel) model.get(BindingResult.MODEL_KEY_PREFIX + "bindBean");