You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by wt...@apache.org on 2019/11/12 21:55:09 UTC
[myfaces] branch master updated: MYFACES-4309: create session in
render response if needed If a given view is not transient and server side
state saving is used,
we should always create a session since some scopes need one. A new parm
ALWAYS_FORCE_SESSION_CREATION (default=false in 3.0) is added to enable
that behavior even if a view is transient or client side state saving is
enabled.
This is an automated email from the ASF dual-hosted git repository.
wtlucy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces.git
The following commit(s) were added to refs/heads/master by this push:
new 8155657 MYFACES-4309: create session in render response if needed If a given view is not transient and server side state saving is used, we should always create a session since some scopes need one. A new parm ALWAYS_FORCE_SESSION_CREATION (default=false in 3.0) is added to enable that behavior even if a view is transient or client side state saving is enabled.
new 23765d9 Merge pull request #73 from wtlucy/MYFACES-4309
8155657 is described below
commit 81556575698ab3b06619a86534165e44e85b0aaa
Author: Bill Lucy <wt...@gmail.com>
AuthorDate: Thu Nov 7 14:49:22 2019 -0500
MYFACES-4309: create session in render response if needed
If a given view is not transient and server side state saving is used, we
should always create a session since some scopes need one. A new parm
ALWAYS_FORCE_SESSION_CREATION (default=false in 3.0) is added to enable
that behavior even if a view is transient or client side state saving
is enabled.
---
.../org/apache/myfaces/config/MyfacesConfig.java | 20 +++++++++++++
.../myfaces/lifecycle/RenderResponseExecutor.java | 35 +++++++++++++++++++++-
2 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java b/impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java
index 0e3300a..c680d4a 100755
--- a/impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java
+++ b/impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java
@@ -806,6 +806,17 @@ public class MyfacesConfig
public static final String RENDER_CLIENTBEHAVIOR_SCRIPTS_AS_STRING = "org.apache.myfaces.RENDER_CLIENTBEHAVIOR_SCRIPTS_AS_STRING";
public static final boolean RENDER_CLIENTBEHAVIOR_SCRIPTS_AS_STRING_DEFAULT = false;
+ /**
+ * Defines if a session should be created (if one does not exist) before response rendering.
+ * When this parameter is set to true, a session will be created even when client side state
+ * saving or stateless views are used, which can lead to unintended resource consumption.
+ * When this parameter is set to false, a session will only be created before response
+ * rendering if a view is not transient and server side state saving is in use.
+ */
+ @JSFWebConfigParam(since="2.3.6", defaultValue="false", expectedValues="true,false")
+ protected static final String ALWAYS_FORCE_SESSION_CREATION =
+ "org.apache.myfaces.ALWAYS_FORCE_SESSION_CREATION";
+ public final static boolean ALWAYS_FORCE_SESSION_CREATION_DEFAULT = false;
// we need it, applicationImpl not ready probably
private ProjectStage projectStage = ProjectStage.Production;
@@ -886,6 +897,7 @@ public class MyfacesConfig
private boolean logWebContextParams = false;
private int websocketMaxConnections = WEBSOCKET_MAX_CONNECTIONS_DEFAULT;
private boolean renderClientBehaviorScriptsAsString = RENDER_CLIENTBEHAVIOR_SCRIPTS_AS_STRING_DEFAULT;
+ private boolean alwaysForceSessionCreation = ALWAYS_FORCE_SESSION_CREATION_DEFAULT;
private static final boolean MYFACES_IMPL_AVAILABLE;
private static final boolean RI_IMPL_AVAILABLE;
@@ -1297,6 +1309,9 @@ public class MyfacesConfig
cfg.renderClientBehaviorScriptsAsString = getBoolean(extCtx, RENDER_CLIENTBEHAVIOR_SCRIPTS_AS_STRING,
RENDER_CLIENTBEHAVIOR_SCRIPTS_AS_STRING_DEFAULT);
+ cfg.alwaysForceSessionCreation = getBoolean(extCtx, ALWAYS_FORCE_SESSION_CREATION,
+ ALWAYS_FORCE_SESSION_CREATION_DEFAULT);
+
return cfg;
}
@@ -1756,5 +1771,10 @@ public class MyfacesConfig
{
return renderClientBehaviorScriptsAsString;
}
+
+ public boolean isAlwaysForceSessionCreation()
+ {
+ return alwaysForceSessionCreation;
+ }
}
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java b/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
index 1ecf911..6a89c90 100644
--- a/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
@@ -29,12 +29,15 @@ import javax.faces.application.FacesMessage;
import javax.faces.application.ProjectStage;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
+import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;
import javax.faces.event.PostRenderViewEvent;
import javax.faces.event.PreRenderViewEvent;
import javax.faces.view.ViewDeclarationLanguage;
+import org.apache.myfaces.shared.config.MyfacesConfig;
+
/**
* Implements the render response phase (JSF Spec 2.2.6)
*
@@ -62,7 +65,9 @@ class RenderResponseExecutor extends PhaseExecutor
{
throw new ViewNotFoundException("A view is required to execute "+facesContext.getCurrentPhaseId());
}
-
+
+ forceSessionCreation(facesContext);
+
try
{
// do-while, because the view might change in PreRenderViewEvent-listeners
@@ -157,4 +162,32 @@ class RenderResponseExecutor extends PhaseExecutor
{
return PhaseId.RENDER_RESPONSE;
}
+
+ /**
+ * Create a session if the ALWAYS_FORCE_SESSION_CREATION param is set to true, or if the
+ * current view is not transient and server side state saving is in use.
+ *
+ * Note: if the current view is transient or client side state saving is in use, it is
+ * not technically correct to create a session here, since a session should not be
+ * required for those cases and creating one will cause undesirable memory usage.
+ * However, if we do not create a session before rendering begins and view or session
+ * scope beans are created later on, then the response might be committed before those
+ * scopes have a chance to create a session and so the session cookie will not be set.
+ * See MYFACES-4309
+ *
+ * @param FacesContext
+ */
+ private void forceSessionCreation(FacesContext context)
+ {
+ if (context.getExternalContext().getSession(false) == null)
+ {
+ ExternalContext ec = context.getExternalContext();
+ if (MyfacesConfig.getCurrentInstance(ec).isAlwaysForceSessionCreation()
+ || (!context.getViewRoot().isTransient()
+ && !context.getApplication().getStateManager().isSavingStateInClient(context)))
+ {
+ context.getExternalContext().getSession(true);
+ }
+ }
+ }
}