Author: markt
Date: Mon Feb 26 10:00:12 2018
New Revision: 1825351
URL: http://svn.apache.org/viewvc?rev=1825351&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=43866
Add additional attributes to the Manager to provide control over which
listeners are called when an attribute is added to the session when it has
already been added under the same name. This is to aid clustering scenarios
where setAttribute() is often called to signal that the attribute value has
been mutated and needs to be replicated but it may not be required, or even
desired, for the the associated listeners to be triggered. The default
behaviour has not been changed.
Modified:
tomcat/trunk/java/org/apache/catalina/Manager.java
tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java
tomcat/trunk/java/org/apache/catalina/session/StandardSession.java
tomcat/trunk/webapps/docs/changelog.xml
tomcat/trunk/webapps/docs/config/manager.xml
Modified: tomcat/trunk/java/org/apache/catalina/Manager.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/Manager.java?rev=1825351&r1=1825350&r2=1825351&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/Manager.java (original)
+++ tomcat/trunk/java/org/apache/catalina/Manager.java Mon Feb 26 10:00:12 2018
@@ -351,4 +351,73 @@ public interface Manager {
* otherwise {@code false}
*/
public boolean willAttributeDistribute(String name, Object value);
+
+
+ /**
+ * When an attribute that is already present in the session is added again
+ * under the same name and the attribute implements {@link
+ * javax.servlet.http.HttpSessionBindingListener}, should
+ * {@link
javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)}
+ * be called followed by
+ * {@link
javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)}?
+ * <p>
+ * The default value is {@code false}.
+ *
+ * @return {@code true} if the listener will be notified, {@code false} if
+ * it will not
+ */
+ public default boolean getNotifyBindingListenerOnUnchangedValue() {
+ return false;
+ }
+
+
+ /**
+ * Configure if
+ * {@link
javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)}
+ * be called followed by
+ * {@link
javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)}
+ * when an attribute that is already present in the session is added again
+ * under the same name and the attribute implements {@link
+ * javax.servlet.http.HttpSessionBindingListener}.
+ *
+ * @param notifyBindingListenerOnUnchangedValue {@code true} the listener
+ * will be called, {@code
+ * false} it will not
+ */
+ public void setNotifyBindingListenerOnUnchangedValue(
+ boolean notifyBindingListenerOnUnchangedValue);
+
+
+ /**
+ * When an attribute that is already present in the session is added again
+ * under the same name and a {@link
+ * javax.servlet.http.HttpSessionAttributeListener} is configured for the
+ * session should
+ * {@link
javax.servlet.http.HttpSessionAttributeListener#attributeReplaced(javax.servlet.http.HttpSessionBindingEvent)}
+ * be called?
+ * <p>
+ * The default value is {@code true}.
+ *
+ * @return {@code true} if the listener will be notified, {@code false} if
+ * it will not
+ */
+ public default boolean getNotifyAttributeListenerOnUnchangedValue() {
+ return true;
+ }
+
+
+ /**
+ * Configure if
+ * {@link
javax.servlet.http.HttpSessionAttributeListener#attributeReplaced(javax.servlet.http.HttpSessionBindingEvent)}
+ * when an attribute that is already present in the session is added again
+ * under the same name and a {@link
+ * javax.servlet.http.HttpSessionAttributeListener} is configured for the
+ * session.
+ *
+ * @param notifyAttributeListenerOnUnchangedValue {@code true} the listener
+ * will be called, {@code
+ * false} it will not
+ */
+ public void setNotifyAttributeListenerOnUnchangedValue(
+ boolean notifyAttributeListenerOnUnchangedValue);
}
Modified: tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java?rev=1825351&r1=1825350&r2=1825351&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java (original)
+++ tomcat/trunk/java/org/apache/catalina/session/ManagerBase.java Mon Feb 26
10:00:12 2018
@@ -193,6 +193,10 @@ public abstract class ManagerBase extend
private boolean warnOnSessionAttributeFilterFailure;
+ private boolean notifyBindingListenerOnUnchangedValue;
+
+ private boolean notifyAttributeListenerOnUnchangedValue = true;
+
// ------------------------------------------------------------
Constructors
@@ -209,6 +213,31 @@ public abstract class ManagerBase extend
// --------------------------------------------------------------
Properties
+ @Override
+ public boolean getNotifyAttributeListenerOnUnchangedValue() {
+ return notifyAttributeListenerOnUnchangedValue;
+ }
+
+
+
+ @Override
+ public void setNotifyAttributeListenerOnUnchangedValue(boolean
notifyAttributeListenerOnUnchangedValue) {
+ this.notifyAttributeListenerOnUnchangedValue =
notifyAttributeListenerOnUnchangedValue;
+ }
+
+
+ @Override
+ public boolean getNotifyBindingListenerOnUnchangedValue() {
+ return notifyBindingListenerOnUnchangedValue;
+ }
+
+
+ @Override
+ public void setNotifyBindingListenerOnUnchangedValue(boolean
notifyBindingListenerOnUnchangedValue) {
+ this.notifyBindingListenerOnUnchangedValue =
notifyBindingListenerOnUnchangedValue;
+ }
+
+
/**
* Obtain the regular expression used to filter session attribute based on
* attribute name. The regular expression is anchored so it must match the
Modified: tomcat/trunk/java/org/apache/catalina/session/StandardSession.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/session/StandardSession.java?rev=1825351&r1=1825350&r2=1825351&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/session/StandardSession.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/session/StandardSession.java Mon Feb
26 10:00:12 2018
@@ -1424,8 +1424,9 @@ public class StandardSession implements
// Call the valueBound() method if necessary
if (notify && value instanceof HttpSessionBindingListener) {
// Don't call any notification if replacing with the same value
+ // unless configured to do so
Object oldValue = attributes.get(name);
- if (value != oldValue) {
+ if (value != oldValue ||
manager.getNotifyBindingListenerOnUnchangedValue()) {
event = new HttpSessionBindingEvent(getSession(), name, value);
try {
((HttpSessionBindingListener) value).valueBound(event);
@@ -1440,14 +1441,18 @@ public class StandardSession implements
Object unbound = attributes.put(name, value);
// Call the valueUnbound() method if necessary
- if (notify && (unbound instanceof HttpSessionBindingListener) &&
(unbound != value)) {
- try {
- ((HttpSessionBindingListener) unbound).valueUnbound(
- new HttpSessionBindingEvent(getSession(), name));
- } catch (Throwable t) {
- ExceptionUtils.handleThrowable(t);
- manager.getContext().getLogger().error(
- sm.getString("standardSession.bindingEvent"), t);
+ if (notify && unbound instanceof HttpSessionBindingListener) {
+ // Don't call any notification if replacing with the same value
+ // unless configured to do so
+ if (unbound != value ||
manager.getNotifyBindingListenerOnUnchangedValue()) {
+ try {
+ ((HttpSessionBindingListener) unbound).valueUnbound
+ (new HttpSessionBindingEvent(getSession(), name));
+ } catch (Throwable t) {
+ ExceptionUtils.handleThrowable(t);
+ manager.getContext().getLogger().error
+ (sm.getString("standardSession.bindingEvent"), t);
+ }
}
}
@@ -1468,12 +1473,14 @@ public class StandardSession implements
HttpSessionAttributeListener listener =
(HttpSessionAttributeListener) listeners[i];
try {
if (unbound != null) {
-
context.fireContainerEvent("beforeSessionAttributeReplaced", listener);
- if (event == null) {
- event = new HttpSessionBindingEvent(getSession(),
name, unbound);
+ if (unbound != value ||
manager.getNotifyAttributeListenerOnUnchangedValue()) {
+
context.fireContainerEvent("beforeSessionAttributeReplaced", listener);
+ if (event == null) {
+ event = new HttpSessionBindingEvent(getSession(),
name, unbound);
+ }
+ listener.attributeReplaced(event);
+
context.fireContainerEvent("afterSessionAttributeReplaced", listener);
}
- listener.attributeReplaced(event);
-
context.fireContainerEvent("afterSessionAttributeReplaced", listener);
} else {
context.fireContainerEvent("beforeSessionAttributeAdded",
listener);
if (event == null) {
@@ -1486,7 +1493,10 @@ public class StandardSession implements
ExceptionUtils.handleThrowable(t);
try {
if (unbound != null) {
-
context.fireContainerEvent("afterSessionAttributeReplaced", listener);
+ if (unbound != value ||
+
manager.getNotifyAttributeListenerOnUnchangedValue()) {
+
context.fireContainerEvent("afterSessionAttributeReplaced", listener);
+ }
} else {
context.fireContainerEvent("afterSessionAttributeAdded", listener);
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1825351&r1=1825350&r2=1825351&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Mon Feb 26 10:00:12 2018
@@ -48,6 +48,16 @@
<subsection name="Catalina">
<changelog>
<fix>
+ <bug>43866</bug>: Add additional attributes to the Manager to provide
+ control over which listeners are called when an attribute is added to
+ the session when it has already been added under the same name. This is
+ to aid clustering scenarios where <code>setAttribute()</code> is often
+ called to signal that the attribute value has been mutated and needs to
+ be replicated but it may not be required, or even desired, for the the
+ associated listeners to be triggered. The default behaviour has not
been
+ changed. (markt)
+ </fix>
+ <fix>
Minor optimization when calling class transformers. (rjung)
</fix>
<add>
Modified: tomcat/trunk/webapps/docs/config/manager.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/manager.xml?rev=1825351&r1=1825350&r2=1825351&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/manager.xml (original)
+++ tomcat/trunk/webapps/docs/config/manager.xml Mon Feb 26 10:00:12 2018
@@ -73,6 +73,23 @@
(e.g. with <code>HttpServletRequest.getSession()</code> call)
will fail with an <code>IllegalStateException</code>.</p>
</attribute>
+
+ <attribute name="notifyAttributeListenerOnUnchangedValue"
required="false">
+ <p>If an attribute is added to the session and that attribute is
already
+ present in the session under the same name will any
+ <code>HttpSessionAttributeListener</code> be notified that the
attribute
+ has been replaced. If not specified, the default value of
+ <code>true</code> will be used.</p>
+ </attribute>
+
+ <attribute name="notifyBindingListenerOnUnchangedValue" required="false">
+ <p>If an attribute is added to the session, that attribute is already
+ present in the session under the same name and the attribute implements
+ <code>HttpSessionBindingListener</code>, will the listener be notified
+ that the attribute has been unbound and bound again. If not specified,
+ the default value of <code>false</code> will be used.</p>
+ </attribute>
+
</attributes>
</subsection>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]