isPostback preserved across redirect before render
The JSF com.sun.faces.facelets.tag.jsf.ComponentSupport in 2.2.7 started using FacesContext#isPostBack to check if a new component tree is being built prior to attempting to find a child component. In Web Flow where we redirect prior to rendering, and hence lose the value of isPostback (because ResponseStateManagerImpl no longer finds the parameter with the view state), it causes components to be re-created and lose their local values. This change overrides isPostback in FlowFacesContext in order to return true in cases where the UIViewRoot has been restored from flash scope and is fully built. Issue: SWF-1645
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user