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:54:58 UTC
[myfaces] branch 2.2.x 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=true in 2.2) 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 2.2.x
in repository https://gitbox.apache.org/repos/asf/myfaces.git
The following commit(s) were added to refs/heads/2.2.x by this push:
new ef681d1 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=true in 2.2) is added to enable that behavior even if a view is transient or client side state saving is enabled.
new 06edf01 Merge pull request #72 from wtlucy/MYFACES-4309_2.2.x
ef681d1 is described below
commit ef681d17bdd3089857216e00971294539948ba04
Author: Bill Lucy <wt...@gmail.com>
AuthorDate: Tue Nov 12 16:20:01 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=true in 2.2) is added to enable
that behavior even if a view is transient or client side state saving
is enabled.
---
.../myfaces/lifecycle/RenderResponseExecutor.java | 38 +++++++++++++++++++++-
.../myfaces/shared/config/MyfacesConfig.java | 32 ++++++++++++++++++
2 files changed, 69 insertions(+), 1 deletion(-)
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 2281e99..d07ee56 100644
--- a/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/RenderResponseExecutor.java
@@ -34,6 +34,8 @@ import javax.faces.event.PhaseId;
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)
*
@@ -44,6 +46,7 @@ class RenderResponseExecutor extends PhaseExecutor
{
private static final Logger log = Logger.getLogger(RenderResponseExecutor.class.getName());
+ private MyfacesConfig _myfacesConfig;
public boolean execute(FacesContext facesContext)
{
@@ -61,7 +64,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
@@ -154,4 +159,35 @@ 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)
+ {
+ if (_myfacesConfig == null)
+ {
+ _myfacesConfig = MyfacesConfig.getCurrentInstance(context.getExternalContext());
+ }
+ if (_myfacesConfig.isAlwaysForceSessionCreation()
+ || (!context.getViewRoot().isTransient()
+ && !context.getApplication().getStateManager().isSavingStateInClient(context)))
+ {
+ context.getExternalContext().getSession(true);
+ }
+ }
+ }
}
diff --git a/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java b/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
index 526d269..69d0954 100755
--- a/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
+++ b/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
@@ -554,6 +554,19 @@ public class MyfacesConfig
"org.apache.myfaces.STRICT_JSF_2_ORIGIN_HEADER_APP_PATH";
public final static boolean STRICT_JSF_2_ORIGIN_HEADER_APP_PATH_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.2.13", defaultValue="true", 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 = true;
+
+
private boolean _prettyHtml;
private boolean _detectJavascript;
private boolean _allowJavascript;
@@ -598,6 +611,7 @@ public class MyfacesConfig
private Integer _numberOfFacesFlowClientWindowIdsInSession;
private boolean _supportEL3ImportHandler;
private boolean _strictJsf2OriginHeaderAppPath;
+ private boolean _alwaysForceSessionCreation;
private static final boolean TOMAHAWK_AVAILABLE;
private static final boolean MYFACES_IMPL_AVAILABLE;
@@ -712,6 +726,7 @@ public class MyfacesConfig
INIT_PARAM_NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION_DEFAULT)+1);
setSupportEL3ImportHandler(SUPPORT_EL_3_IMPORT_HANDLER_DEFAULT);
setStrictJsf2OriginHeaderAppPath(STRICT_JSF_2_ORIGIN_HEADER_APP_PATH_DEFAULT);
+ setAlwaysForceSessionCreation(ALWAYS_FORCE_SESSION_CREATION_DEFAULT);
}
private static MyfacesConfig createAndInitializeMyFacesConfig(ExternalContext extCtx)
@@ -915,6 +930,10 @@ public class MyfacesConfig
myfacesConfig.setStrictJsf2OriginHeaderAppPath(WebConfigParamUtils.getBooleanInitParameter(extCtx,
STRICT_JSF_2_ORIGIN_HEADER_APP_PATH,
STRICT_JSF_2_ORIGIN_HEADER_APP_PATH_DEFAULT));
+
+ myfacesConfig.setAlwaysForceSessionCreation(WebConfigParamUtils.getBooleanInitParameter(extCtx,
+ ALWAYS_FORCE_SESSION_CREATION,
+ ALWAYS_FORCE_SESSION_CREATION_DEFAULT));
if (TOMAHAWK_AVAILABLE)
{
@@ -1593,4 +1612,17 @@ public class MyfacesConfig
{
this._strictJsf2OriginHeaderAppPath = strictJsf2OriginHeaderAppPath;
}
+
+ public boolean isAlwaysForceSessionCreation()
+ {
+ return _alwaysForceSessionCreation;
+ }
+
+ /**
+ * @param alwaysForceSessionCreation the _alwaysForceSessionCreation to set
+ */
+ public void setAlwaysForceSessionCreation(boolean alwaysForceSessionCreation)
+ {
+ this._alwaysForceSessionCreation = alwaysForceSessionCreation;
+ }
}