package com.hehenian.common.session; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.util.Assert; import com.hehenian.common.session.cache.SessionCache; import com.hehenian.common.session.id.SessionIdGenerator; import com.hehenian.common.utils.CommonUtil; /** * 使用Memcached分布式缓存实现Session */ public class CacheSessionProvider implements SessionProvider, InitializingBean { public static final String CURRENT_SESSION = "_current_session"; public static final String CURRENT_SESSION_ID = "_current_session_id"; @SuppressWarnings("unchecked") public Serializable getAttribute(HttpServletRequest request, String name) { // 为了避免同一个请求多次获取缓存session,所以将缓存session保存至request中。 Map<String, Serializable> session = (Map<String, Serializable>) request.getAttribute(CURRENT_SESSION); if (session != null) { return session.get(name); } String root = (String) request.getAttribute(CURRENT_SESSION_ID); if (root == null) { root = CommonUtil.getRequestedSessionId(request); } if (StringUtils.isBlank(root)) { request.setAttribute(CURRENT_SESSION, new HashMap<String, Serializable>()); return null; } session = sessionCache.getSession(root); if (session != null) { request.setAttribute(CURRENT_SESSION_ID, root); request.setAttribute(CURRENT_SESSION, session); return session.get(name); } else { return null; } } @SuppressWarnings("unchecked") public void setAttribute(HttpServletRequest request, HttpServletResponse response, String name, Serializable value) { Map<String, Serializable> session = (Map<String, Serializable>) request.getAttribute(CURRENT_SESSION); String root; if (session == null) { root = CommonUtil.getRequestedSessionId(request); if (root != null && root.length() == 32) { session = sessionCache.getSession(root); } if (session == null) { session = new HashMap<String, Serializable>(); do { root = sessionIdGenerator.get(); } while (sessionCache.exist(root)); response.addCookie(createCookie(request, root)); } request.setAttribute(CURRENT_SESSION, session); request.setAttribute(CURRENT_SESSION_ID, root); } else { root = (String) request.getAttribute(CURRENT_SESSION_ID); if (root == null) { do { root = sessionIdGenerator.get(); } while (sessionCache.exist(root)); response.addCookie(createCookie(request, root)); request.setAttribute(CURRENT_SESSION_ID, root); } } session.put(name, value); sessionCache.setSession(root, session, sessionTimeout); } public String getSessionId(HttpServletRequest request, HttpServletResponse response) { String root = (String) request.getAttribute(CURRENT_SESSION_ID); if (root != null) { return root; } root = CommonUtil.getRequestedSessionId(request); if (root == null || root.length() != 32 || !sessionCache.exist(root)) { do { root = sessionIdGenerator.get(); } while (sessionCache.exist(root)); sessionCache.setSession(root, new HashMap<String, Serializable>(), sessionTimeout); response.addCookie(createCookie(request, root)); } request.setAttribute(CURRENT_SESSION_ID, root); return root; } public void logout(HttpServletRequest request, HttpServletResponse response) { request.removeAttribute(CURRENT_SESSION); request.removeAttribute(CURRENT_SESSION_ID); String root = CommonUtil.getRequestedSessionId(request); if (!StringUtils.isBlank(root)) { sessionCache.clear(root); Cookie cookie = createCookie(request, null); cookie.setMaxAge(0); response.addCookie(cookie); } } private Cookie createCookie(HttpServletRequest request, String value) { Cookie cookie = new Cookie(CommonUtil.JSESSION_COOKIE, value); String ctx = request.getContextPath(); cookie.setPath(StringUtils.isBlank(ctx) ? "/" : ctx); cookie.setDomain(".hehenian.com"); return cookie; } public void afterPropertiesSet() throws Exception { Assert.notNull(sessionCache); Assert.notNull(sessionIdGenerator); } private SessionCache sessionCache; private SessionIdGenerator sessionIdGenerator; private int sessionTimeout = 30; public void setSessionCache(SessionCache sessionCache) { this.sessionCache = sessionCache; } /** * 设置session过期时间 * * @param sessionTimeout * 分钟 */ public void setSessionTimeout(int sessionTimeout) { Assert.isTrue(sessionTimeout > 0); this.sessionTimeout = sessionTimeout; } public void setSessionIdGenerator(SessionIdGenerator sessionIdGenerator) { this.sessionIdGenerator = sessionIdGenerator; } }