Skip to content

Commit eaeb9e4

Browse files
committed
Introduce SessionRepositoryFilter::setCommitSessionOncePerRequest
Fix spring-projects#1424 See spring-projects#1910
1 parent 2d4233f commit eaeb9e4

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java

+17
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
106106

107107
private HttpSessionIdResolver httpSessionIdResolver = new CookieHttpSessionIdResolver();
108108

109+
private boolean commitSessionOncePerRequest = false;
110+
109111
/**
110112
* Creates a new instance.
111113
* @param sessionRepository the <code>SessionRepository</code> to use. Cannot be null.
@@ -130,6 +132,15 @@ public void setHttpSessionIdResolver(HttpSessionIdResolver httpSessionIdResolver
130132
this.httpSessionIdResolver = httpSessionIdResolver;
131133
}
132134

135+
/**
136+
* Sets the {@link #commitSessionOncePerRequest} to be used. The default is a
137+
* {@code false}.
138+
* @param commitSessionOncePerRequest the value to use.
139+
*/
140+
public void setCommitSessionOncePerRequest(boolean commitSessionOncePerRequest) {
141+
this.commitSessionOncePerRequest = commitSessionOncePerRequest;
142+
}
143+
133144
@Override
134145
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
135146
throws ServletException, IOException {
@@ -207,6 +218,8 @@ private final class SessionRepositoryRequestWrapper extends HttpServletRequestWr
207218

208219
private boolean hasCommittedInInclude;
209220

221+
private boolean committed;
222+
210223
private SessionRepositoryRequestWrapper(HttpServletRequest request, HttpServletResponse response) {
211224
super(request);
212225
this.response = response;
@@ -217,6 +230,10 @@ private SessionRepositoryRequestWrapper(HttpServletRequest request, HttpServletR
217230
* and persist the Session.
218231
*/
219232
private void commitSession() {
233+
if (this.committed && SessionRepositoryFilter.this.commitSessionOncePerRequest) {
234+
return;
235+
}
236+
this.committed = true;
220237
HttpSessionWrapper wrappedSession = getCurrentSession();
221238
if (wrappedSession == null) {
222239
if (isInvalidateClientSession()) {

spring-session-core/src/test/java/org/springframework/session/web/http/SessionRepositoryFilterTests.java

+30
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
import org.junit.jupiter.api.BeforeEach;
4545
import org.junit.jupiter.api.Test;
4646
import org.junit.jupiter.api.extension.ExtendWith;
47+
import org.junit.jupiter.params.ParameterizedTest;
48+
import org.junit.jupiter.params.provider.ValueSource;
4749
import org.mockito.Mock;
4850
import org.mockito.junit.jupiter.MockitoExtension;
4951

@@ -1346,6 +1348,34 @@ public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrap
13461348
});
13471349
}
13481350

1351+
@ParameterizedTest
1352+
@ValueSource(booleans = { false, true })
1353+
void commitSessionOncePerRequest(boolean commitSessionOncePerRequest) throws Exception {
1354+
MapSession session = this.sessionRepository.createSession();
1355+
this.sessionRepository.save(session);
1356+
SessionRepository<MapSession> sessionRepository = spy(this.sessionRepository);
1357+
setSessionCookie(session.getId());
1358+
1359+
given(sessionRepository.findById(session.getId())).willReturn(session);
1360+
1361+
this.filter = new SessionRepositoryFilter<>(sessionRepository);
1362+
this.filter.setCommitSessionOncePerRequest(commitSessionOncePerRequest);
1363+
1364+
doFilter(new DoInFilter() {
1365+
@Override
1366+
public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse)
1367+
throws IOException, ServletException {
1368+
String id = wrappedRequest.getSession().getId();
1369+
wrappedResponse.getOutputStream().close(); // trigger commitSession()
1370+
assertThat(SessionRepositoryFilterTests.this.sessionRepository.findById(id)).isNotNull();
1371+
}
1372+
});
1373+
int times = commitSessionOncePerRequest ? 1 : 2;
1374+
verify(sessionRepository, times(times)).findById(session.getId());
1375+
verify(sessionRepository, times(times)).save(session);
1376+
verifyNoMoreInteractions(sessionRepository);
1377+
}
1378+
13491379
// --- helper methods
13501380

13511381
private void assertNewSession() {

0 commit comments

Comments
 (0)