diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java index 2a9568b01716..a4f821035d79 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java @@ -69,6 +69,8 @@ public class SessionAttributesHandler { private final SessionAttributeStore sessionAttributeStore; + private final String sessionKnownAttribute; + /** * Create a new session attributes handler. Session attribute names and types @@ -80,6 +82,7 @@ public class SessionAttributesHandler { public SessionAttributesHandler(Class handlerType, SessionAttributeStore sessionAttributeStore) { Assert.notNull(sessionAttributeStore, "SessionAttributeStore may not be null"); this.sessionAttributeStore = sessionAttributeStore; + this.sessionKnownAttribute = SessionAttributesHandler.class.getName() + ".KNOWN." + handlerType.getName(); SessionAttributes ann = AnnotatedElementUtils.findMergedAnnotation(handlerType, SessionAttributes.class); if (ann != null) { @@ -135,7 +138,7 @@ public void storeAttributes(WebRequest request, Map attributes) { // Only necessary for type-based attributes which get added to knownAttributeNames when touched. if (!this.attributeTypes.isEmpty()) { this.sessionAttributeStore.storeAttribute(request, - SESSION_KNOWN_ATTRIBUTE, StringUtils.toStringArray(this.knownAttributeNames)); + this.sessionKnownAttribute, StringUtils.toStringArray(this.knownAttributeNames)); } } @@ -150,7 +153,7 @@ public Map retrieveAttributes(WebRequest request) { // Restore known attribute names from session (for distributed sessions) // Only necessary for type-based attributes which get added to knownAttributeNames when touched. if (!this.attributeTypes.isEmpty()) { - Object known = this.sessionAttributeStore.retrieveAttribute(request, SESSION_KNOWN_ATTRIBUTE); + Object known = this.sessionAttributeStore.retrieveAttribute(request, this.sessionKnownAttribute); if (known instanceof String[] retrievedAttributeNames) { this.knownAttributeNames.addAll(Arrays.asList(retrievedAttributeNames)); } diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/SessionAttributesHandlerTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/SessionAttributesHandlerTests.java index 2f1dca0adc78..87ee142054ed 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/SessionAttributesHandlerTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/SessionAttributesHandlerTests.java @@ -107,9 +107,45 @@ void storeAttributes() { assertThat(sessionAttributeStore.retrieveAttribute(request, "attr3")).isInstanceOf(TestBean.class); } + @Test + void retrieveAttributesDoesNotReturnAttributesForAnotherHandlerType() { + ModelMap model = new ModelMap(); + model.put("testBean", new TestBean()); + + sessionAttributesHandler.storeAttributes(request, model); + + SessionAttributesHandler anotherHandler = + new SessionAttributesHandler(AnotherTestSessionAttributesHolder.class, sessionAttributeStore); + + assertThat(anotherHandler.retrieveAttributes(request)) + .as("A handler should not retrieve session attributes for a different handler type") + .isEmpty(); + } + + @Test + void cleanupAttributesDoesNotRemoveAttributesForAnotherHandlerType() { + TestBean testBean = new TestBean(); + ModelMap model = new ModelMap("testBean", testBean); + sessionAttributesHandler.storeAttributes(request, model); + + SessionAttributesHandler anotherHandler = + new SessionAttributesHandler(AnotherTestSessionAttributesHolder.class, sessionAttributeStore); + + // Restore known attribute names before cleanup + anotherHandler.retrieveAttributes(request); + anotherHandler.cleanupAttributes(request); + + assertThat(sessionAttributeStore.retrieveAttribute(request, "testBean")) + .as("A handler should not remove a session attribute for a different handler type") + .isSameAs(testBean); + } @SessionAttributes(names = {"attr1", "attr2"}, types = TestBean.class) private static class TestSessionAttributesHolder { } + @SessionAttributes(types = TestBean.class) + private static class AnotherTestSessionAttributesHolder { + } + }