diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java index e25cc5e4..9c960861 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowFacesContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2012 the original author or authors. + * Copyright 2004-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; - import javax.el.ELContext; import javax.faces.application.FacesMessage; import javax.faces.context.ExternalContext; @@ -92,6 +91,9 @@ public class FlowFacesContext extends FacesContextWrapper { private final PartialViewContext partialViewContext; + private boolean viewRootHolderFromFlashScope; + + public FlowFacesContext(RequestContext context, FacesContext wrapped) { this.context = context; this.wrapped = wrapped; @@ -259,6 +261,23 @@ public class FlowFacesContext extends FacesContextWrapper { return new FacesMessage(severity, message.getText(), null); } + /** + * This flag is set internally when the UIViewRoot is restored following a + * redirect and prior to rendering and is then checked whether to return + * {@code true} from {@link #isPostback()} so that JSF (2.2.7+) won't think + * it's building a new component tree. + * @see com.sun.faces.facelets.tag.jsf.ComponentSupport#isBuildingNewComponentTree + * @since 2.4.2 + */ + void setViewRootRestoredFromFlashScope() { + this.viewRootHolderFromFlashScope = true; + } + + @Override + public boolean isPostback() { + return (this.viewRootHolderFromFlashScope || super.isPostback()); + } + public static FlowFacesContext newInstance(RequestContext context, Lifecycle lifecycle) { FacesContext defaultFacesContext = newDefaultInstance(context, lifecycle); return new FlowFacesContext(context, defaultFacesContext); diff --git a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java index 4dd272b5..a3768f5e 100644 --- a/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java +++ b/spring-faces/src/main/java/org/springframework/faces/webflow/FlowViewHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2004-2012 the original author or authors. + * Copyright 2004-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.faces.webflow; import java.util.Locale; - import javax.faces.application.ViewHandler; import javax.faces.application.ViewHandlerWrapper; import javax.faces.component.UIViewRoot; @@ -118,6 +117,9 @@ public class FlowViewHandler extends ViewHandlerWrapper { RequestContext context = RequestContextHolder.getRequestContext(); ViewRootHolder holder = (ViewRootHolder) context.getFlashScope().get(View.USER_EVENT_STATE_ATTRIBUTE); if (holder != null && holder.getViewRoot() != null && holder.getViewRoot().getViewId().equals(resourcePath)) { + if (facesContext instanceof FlowFacesContext) { + ((FlowFacesContext) facesContext).setViewRootRestoredFromFlashScope(); + } return holder.getViewRoot(); } else { return super.restoreView(facesContext, resourcePath);