diff --git a/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java b/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java index 164d91ca..b5e016c9 100644 --- a/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java +++ b/spring-session-core/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.session.web.http; import java.io.IOException; import java.time.Instant; +import java.util.List; import javax.servlet.FilterChain; import javax.servlet.ServletContext; @@ -196,14 +197,18 @@ public class SessionRepositoryFilter extends OncePerRequestFi private final class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper { - private Boolean requestedSessionIdValid; - - private boolean requestedSessionInvalidated; - private final HttpServletResponse response; private final ServletContext servletContext; + private S requestedSession; + + private boolean requestedSessionCached; + + private Boolean requestedSessionIdValid; + + private boolean requestedSessionInvalidated; + private SessionRepositoryRequestWrapper(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) { super(request); @@ -225,7 +230,7 @@ public class SessionRepositoryFilter extends OncePerRequestFi } else { S session = wrappedSession.getSession(); - SessionRepositoryFilter.this.sessionRepository.save(session); + saveSession(session); String sessionId = session.getId(); if (!isRequestedSessionIdValid() || !sessionId.equals(getRequestedSessionId())) { @@ -265,9 +270,11 @@ public class SessionRepositoryFilter extends OncePerRequestFi @Override public boolean isRequestedSessionIdValid() { if (this.requestedSessionIdValid == null) { - String sessionId = getRequestedSessionId(); - S session = sessionId == null ? null : getSession(sessionId); - return isRequestedSessionIdValid(session); + S requestedSession = getRequestedSession(); + if (requestedSession != null) { + requestedSession.setLastAccessedTime(Instant.now()); + } + return isRequestedSessionIdValid(requestedSession); } return this.requestedSessionIdValid; @@ -284,28 +291,18 @@ public class SessionRepositoryFilter extends OncePerRequestFi return getCurrentSession() == null && this.requestedSessionInvalidated; } - private S getSession(String sessionId) { - S session = SessionRepositoryFilter.this.sessionRepository - .findById(sessionId); - if (session == null) { - return null; - } - session.setLastAccessedTime(Instant.now()); - return session; - } - @Override public HttpSessionWrapper getSession(boolean create) { HttpSessionWrapper currentSession = getCurrentSession(); if (currentSession != null) { return currentSession; } - String requestedSessionId = getRequestedSessionId(); - if (requestedSessionId != null) { + S requestedSession = getRequestedSession(); + if (requestedSession != null) { if (getAttribute(INVALID_SESSION_ID_ATTR) == null) { - S session = getSession(requestedSessionId); + requestedSession.setLastAccessedTime(Instant.now()); this.requestedSessionIdValid = true; - currentSession = new HttpSessionWrapper(session, getServletContext()); + currentSession = new HttpSessionWrapper(requestedSession, getServletContext()); currentSession.setNew(false); setCurrentSession(currentSession); return currentSession; @@ -353,11 +350,31 @@ public class SessionRepositoryFilter extends OncePerRequestFi @Override public String getRequestedSessionId() { - return SessionRepositoryFilter.this.httpSessionIdResolver - .resolveSessionIds(this).stream() - .filter(sessionId -> SessionRepositoryFilter.this.sessionRepository - .findById(sessionId) != null) - .findFirst().orElse(null); + S requestedSession = getRequestedSession(); + return (requestedSession != null ? requestedSession.getId() : null); + } + + private S getRequestedSession() { + if (!this.requestedSessionCached) { + List sessionIds = SessionRepositoryFilter.this.httpSessionIdResolver + .resolveSessionIds(this); + for (String sessionId : sessionIds) { + S session = SessionRepositoryFilter.this.sessionRepository + .findById(sessionId); + if (session != null) { + this.requestedSession = session; + break; + } + } + this.requestedSessionCached = true; + } + return this.requestedSession; + } + + private void saveSession(S session) { + this.requestedSessionCached = false; + this.requestedSession = null; + SessionRepositoryFilter.this.sessionRepository.save(session); } /** diff --git a/spring-session-core/src/test/java/org/springframework/session/config/annotation/web/http/EnableSpringHttpSessionCustomCookieSerializerTests.java b/spring-session-core/src/test/java/org/springframework/session/config/annotation/web/http/EnableSpringHttpSessionCustomCookieSerializerTests.java index 4fde069e..2f6c5458 100644 --- a/spring-session-core/src/test/java/org/springframework/session/config/annotation/web/http/EnableSpringHttpSessionCustomCookieSerializerTests.java +++ b/spring-session-core/src/test/java/org/springframework/session/config/annotation/web/http/EnableSpringHttpSessionCustomCookieSerializerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2017 the original author or authors. + * Copyright 2014-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; /** @@ -82,6 +83,9 @@ public class EnableSpringHttpSessionCustomCookieSerializerTests { @Before public void setup() { this.chain = new MockFilterChain(); + + reset(this.sessionRepository); + reset(this.cookieSerializer); } @Test @@ -99,7 +103,7 @@ public class EnableSpringHttpSessionCustomCookieSerializerTests { @Test public void usesWrite() throws Exception { - given(this.sessionRepository.findById(anyString())).willReturn(new MapSession()); + given(this.sessionRepository.createSession()).willReturn(new MapSession()); this.sessionRepositoryFilter.doFilter(this.request, this.response, new MockFilterChain() {