Make Servlet 2.5 compatible

Fixes gh-111 gh-182
This commit is contained in:
Rob Winch
2015-04-07 22:12:40 -05:00
parent 5417e59a50
commit 4631b57531
21 changed files with 110 additions and 30 deletions

View File

@@ -45,11 +45,13 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR
import org.springframework.session.events.SessionDestroyedEvent;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import redis.embedded.RedisServer;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class RedisOperationsSessionRepositoryITests<S extends Session> {
@Autowired
private SessionRepository<S> repository;

View File

@@ -45,11 +45,13 @@ import org.springframework.session.SessionRepository;
import org.springframework.session.events.SessionDestroyedEvent;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import redis.embedded.RedisServer;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends ExpiringSession> {
@Autowired
private SessionRepository<S> repository;

View File

@@ -19,6 +19,8 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
@@ -99,8 +101,9 @@ public class RedisHttpSessionConfiguration implements ImportAware, BeanClassLoad
}
@Bean
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository) {
public <S extends ExpiringSession> SessionRepositoryFilter<? extends ExpiringSession> springSessionRepositoryFilter(SessionRepository<S> sessionRepository, ServletContext servletContext) {
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<S>(sessionRepository);
sessionRepositoryFilter.setServletContext(servletContext);
if(httpSessionStrategy != null) {
sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy);
}

View File

@@ -23,6 +23,7 @@ import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -161,6 +162,8 @@ public final class CookieHttpSessionStrategy implements MultiHttpSessionStrategy
private String sessionParam = DEFAULT_SESSION_ALIAS_PARAM_NAME;
private boolean isServlet3Plus = isServlet3();
public String getRequestedSessionId(HttpServletRequest request) {
Map<String,String> sessionIds = getSessionIds(request);
String sessionAlias = getCurrentSessionAlias(request);
@@ -215,7 +218,9 @@ public final class CookieHttpSessionStrategy implements MultiHttpSessionStrategy
private Cookie createSessionCookie(HttpServletRequest request,
Map<String, String> sessionIds) {
Cookie sessionCookie = new Cookie(cookieName,"");
sessionCookie.setHttpOnly(true);
if(isServlet3Plus) {
sessionCookie.setHttpOnly(true);
}
sessionCookie.setSecure(request.isSecure());
sessionCookie.setPath(cookiePath(request));
// TODO set domain?
@@ -387,4 +392,16 @@ public final class CookieHttpSessionStrategy implements MultiHttpSessionStrategy
throw new RuntimeException(e);
}
}
/**
* Returns true if the Servlet 3 APIs are detected.
* @return
*/
private boolean isServlet3() {
try {
ServletRequest.class.getMethod("startAsync");
return true;
} catch(NoSuchMethodException e) {}
return false;
}
}

View File

@@ -66,6 +66,8 @@ public class SessionRepositoryFilter<S extends ExpiringSession> extends OncePerR
private final SessionRepository<S> sessionRepository;
private ServletContext servletContext;
private MultiHttpSessionStrategy httpSessionStrategy = new CookieHttpSessionStrategy();
/**
@@ -107,7 +109,7 @@ public class SessionRepositoryFilter<S extends ExpiringSession> extends OncePerR
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
request.setAttribute(SESSION_REPOSITORY_ATTR, sessionRepository);
SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(request, response);
SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(request, response, servletContext);
SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(wrappedRequest,response);
HttpServletRequest strategyRequest = httpSessionStrategy.wrapRequest(wrappedRequest, wrappedResponse);
@@ -120,6 +122,10 @@ public class SessionRepositoryFilter<S extends ExpiringSession> extends OncePerR
}
}
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
/**
* Allows ensuring that the session is saved if the response is committed.
*
@@ -158,10 +164,12 @@ public class SessionRepositoryFilter<S extends ExpiringSession> extends OncePerR
private HttpSessionWrapper currentSession;
private Boolean requestedSessionIdValid;
private final HttpServletResponse response;
private final ServletContext servletContext;
private SessionRepositoryRequestWrapper(HttpServletRequest request, HttpServletResponse response) {
private SessionRepositoryRequestWrapper(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) {
super(request);
this.response = response;
this.servletContext = servletContext;
}
/**
@@ -257,6 +265,14 @@ public class SessionRepositoryFilter<S extends ExpiringSession> extends OncePerR
return currentSession;
}
public ServletContext getServletContext() {
if(servletContext != null) {
return servletContext;
}
// Servlet 3.0+
return super.getServletContext();
}
@Override
public HttpSession getSession() {
return getSession(true);

View File

@@ -24,9 +24,11 @@ import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class RedisHttpSessionConfigurationXmlCustomExpireTests {
@Test

View File

@@ -24,9 +24,11 @@ import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class RedisHttpSessionConfigurationXmlTests {
@Test

View File

@@ -50,6 +50,7 @@ import org.springframework.core.annotation.OrderUtils;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletContext;
import org.springframework.session.ExpiringSession;
import org.springframework.session.MapSessionRepository;
import org.springframework.session.Session;
@@ -188,6 +189,22 @@ public class SessionRepositoryFilterTests<S extends ExpiringSession> {
});
}
// gh-111
@Test
public void doFilterServletContextExplicit() throws Exception {
final ServletContext expectedContext = new MockServletContext();
filter = new SessionRepositoryFilter<ExpiringSession>(sessionRepository);
filter.setServletContext(expectedContext);
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest) {
ServletContext context = wrappedRequest.getSession().getServletContext();
assertThat(context).isSameAs(expectedContext);
}
});
}
@Test
public void doFilterMaxInactiveIntervalDefault() throws Exception {
doFilter(new DoInFilter() {