Memcached儲存sessionId

來源:互聯網
上載者:User

標籤:http   java   os   io   資料   for   ar   代碼   

1、把sessionId存放在cookie中,並設定一個有效期間;
2、把經過Serializable序列化的對象存放在memcached中,同時設定一個失效時間,比如1小時;
3、每次取會話資訊時,先從cookie中取sessionId,如果cookie不存在,則說明會話已到期;如果會話存在,則從memcached中讀取會話資訊,如果會話資訊不存在,則從資料庫中讀取相關資訊,然後放在memcached中,同時設定失效時間;
4、設定一個filter,在每次請求時,更新會話cookie的失效時間;
5、登入時設定一個隱藏的隨機數;
6、退出時刪除會話cookie,同時從memcached中刪除相關的會話;

代碼如下:

RequestUtils.java

package com.util;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**

*對cookie讀寫

*/

public class RequestUtils
{

 public static String cookieDomain = "";

 public static String cookiePath = "/";
 
 /**
  * 擷取COOKIE
  * @param request
  * @param name
  */
 public static Cookie getCookie(HttpServletRequest request, String name) {
  Cookie[] cookies = request.getCookies();
  if(cookies == null)
   return null;
  for (int i = 0; i < cookies.length; i++) {
   if (name.equals(cookies[i].getName())) {
    return cookies[i];
   }
  }
  return null;
 }

 /**
  * 設定COOKIE
  * @param request
  * @param response
  * @param name
  * @param value
  * @param maxAge
  */
 public static void setCookie(HttpServletRequest request, HttpServletResponse response, String name,
   String value, int maxAge)
 {
  Cookie cookie = new Cookie(name, value);
  cookie.setMaxAge(maxAge);
  if(cookieDomain!=null && cookieDomain.indexOf(‘.‘)!=-1){
   cookie.setDomain(‘.‘ + cookieDomain);
  }
  cookie.setPath(cookiePath);
  response.addCookie(cookie);
 }
 }

//

SessionCookieFilter.java

package com.mem.session;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.util.RequestUtils;

/**

*對每次動態網頁面的請求時,更新會話cookie的有效期間

*/

public class SessionCookieFilter extends HttpServlet implements Filter
{
 /**
  *
  */
 private static final long serialVersionUID = -6516046520244652987L;

 private String sessionId = "sid";
 
 private int expiryDate = 30*60;//seconeds
 
 public void doFilter(ServletRequest servletRequest,
   ServletResponse servletResponse, FilterChain filterChain)
   throws IOException, ServletException
 { 
  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletResponse;
  Cookie cookie = RequestUtils.getCookie(request, sessionId); 
  if (cookie != null)
  {
   String sid = cookie.getValue();
   //設定cookie的有效期間
   RequestUtils.setCookie(request, response, sessionId, sid, expiryDate);
  }
  filterChain.doFilter(request,response);
 }

 public void init(FilterConfig filterConfig) throws ServletException
 {
  this.sessionId = filterConfig.getInitParameter("sessionId");
 
  com.util.RequestUtils.cookieDomain = filterConfig.getInitParameter("cookieDomain");
  if (com.util.RequestUtils.cookieDomain == null)
  {
   com.util.RequestUtils.cookieDomain = "";
  }

  com.util.RequestUtils.cookiePath = filterConfig.getInitParameter("cookiePath");
  if (com.util.RequestUtils.cookiePath == null || com.util.RequestUtils.cookiePath.length() == 0)
  {
   com.util.RequestUtils.cookiePath = "/";
  }
 }

}

//

SessionService.java

package com.mem.session;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Calendar;
import java.util.Date;

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;

/**

*對memcached的操作

*/

public class SessionService {

 private static SessionService instance = null;

 private SockIOPool pool = null;

 private String poolName = "sidsock";
 
 private int expiryTime = 60;//minutes
 
 private Date getExpiryDate()
 {
  Calendar calendar = Calendar.getInstance();
 
  long time = calendar.getTimeInMillis();
  time += expiryTime * 60 * 1000;
  calendar.setTimeInMillis(time);
 
  return calendar.getTime();
 }

 public static synchronized SessionService getInstance() {
  if (instance == null) {
   instance = new SessionService();
  }
  return instance;
 }

 private SessionService() {
  ClassLoader cl = Thread.currentThread().getContextClassLoader();
  InputStream input = cl.getResourceAsStream("memcached.properties");
  Properties props = new Properties();
  String serverlist = "127.0.0.1:11211";
  try {
   props.load(input);
   serverlist = props.getProperty("serverlist", "127.0.0.1:11211");
   poolName = props.getProperty("poolname", "sidsock");

  } catch (Exception e) {
   e.printStackTrace();
  }

  String[] servers = serverlist.split(",");
  pool = SockIOPool.getInstance(poolName);
  pool.setServers(servers);
  pool.setFailover(true);
  pool.setInitConn(10);
  pool.setMinConn(5);
  pool.setMaxConn(250);
  pool.setMaintSleep(30);
  pool.setNagle(false);
  pool.setSocketTO(3000);
  pool.setAliveCheck(true);
  pool.initialize();
 }

 public boolean sessionExists(String id)
 {
  MemCachedClient mc = this.getMemCachedClient();
  return  mc.keyExists(id);
 }
 public Map getSession(String id,boolean create)
 {
  MemCachedClient mc = this.getMemCachedClient();
 
  Map session = (Map) mc.get(id);
  if(session == null)
  {
   if(create)
   {
    session = new HashMap(5);
    mc.add(id, session,getExpiryDate());
   }
  }
  return session;
 }

 public void saveSession(String id, Map session)
 {
  MemCachedClient mc = this.getMemCachedClient();
  if(mc.keyExists(id))
  {
   mc.replace(id, session);
  }
  else
  {
   mc.add(id, session);
  }
 }
 
 public void saveSession(String id, Map session,Date expiryDate)
 {
  MemCachedClient mc = this.getMemCachedClient();
  if(mc.keyExists(id))
  {
   mc.replace(id, session,expiryDate);
  }
  else
  {
   mc.add(id, session,expiryDate);
  }
 }

 public void removeSession(String id)
 {
  MemCachedClient mc = this.getMemCachedClient();
  mc.delete(id);
 }

 public void updateExpiryDate(String id)
 {
  MemCachedClient mc = this.getMemCachedClient();
  Map session = (Map) mc.get(id);
  if(session != null)
  {
   mc.replace(id, session,getExpiryDate());
  }
 }
 
 private MemCachedClient getMemCachedClient()
 {
  MemCachedClient mc = new MemCachedClient();
  mc.setPoolName(poolName);
  mc.setCompressEnable(false);
  mc.setCompressThreshold(0);
  return mc;
 }

 protected void finalize()
 {
  if (this.pool != null)
  {
   this.pool.shutDown();
  }
 }

}


//

MemSession.java

package com.mem.session;

import java.util.Map;

/**

*對會話的操作

*/

public class MemSession
{
 //會話ID
 private String sid = "";

 //存放本會話的所有資訊
 private Map map = null;
 
 public static MemSession getSession(String sid)
 {
  MemSession session = null;
 
  session = new MemSession(sid,true);
 
  return session;
 }
 
 public static MemSession getSession(String sid,boolean create)
 {
  MemSession session = null;
 
  session = new MemSession(sid,create);
 
  return session;
 }

 private MemSession(String sid,boolean create)
 {
  this.sid = sid;
  this.map = SessionService.getInstance().getSession(sid,create);
 }

 public static boolean sessionExists(String sid)
 {
  return SessionService.getInstance().sessionExists(sid);
 }
 
 public Object getAttribute(String arg0)
 {
  return this.map.get(arg0);
 }

 public void invalidate()
 {
  this.map.clear();
  SessionService.getInstance().removeSession(this.sid);
 }

 public void removeAttribute(String arg0)
 {
  if(arg0 == null || arg0.trim().length() <= 0)
  {
   return;
  }
  this.map.remove(arg0);
  SessionService.getInstance().saveSession(this.sid, this.map);
 }
 public void setAttribute(String arg0, Object arg1)
 {
  if(arg0 == null || arg0.trim().length() <= 0 || arg1 == null)
  {
   return ;
  }
  this.map.put(arg0, arg1);
  SessionService.getInstance().saveSession(this.sid, this.map);
 }
 public void updateExpiryDate(String sid)
 {
  SessionService.getInstance().updateExpiryDate(sid);
 }
 
}


//SessionUtil.java

package com.mem.session;

import java.io.Serializable;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.util.RequestUtils;
import com.mem.session.MemSession;

public class SessionUtil
{
 public static UserInfo getUserInfo(HttpServletRequest request)
 {
  Cookie cookie = RequestUtils.getCookie(request, "sid");
 
  if(cookie != null)
  {
   String sid = cookie.getValue();
   MemSession session = MemSession.getSession(sid);
   UserInfo userInfo = (UserInfo)session.getAttribute("user_session_flag");
  
   if(userInfo == null)
   {
    //緩衝中已經不存在,則要從資料庫中讀取,同時存放在緩衝中
    userInfo = new UserInfo("hpt321",1,"hpt321");//要從資料庫中讀取
    session.setAttribute("user_session_flag", userInfo);
   
    return userInfo;
   }
  
  }
  return null;
 }
 
 public static void setUserInfo(UserInfo userInfo,HttpServletRequest request,HttpServletResponse response)
 {
  setAttribute(request, "user_session_flag", userInfo);
 }
 /**
  * 登入返回true;未登入返回false;
  * @param request
  * @return
  */
 public static boolean valideLogin(HttpServletRequest request)
 {
  Cookie cookie = RequestUtils.getCookie(request, "sid");
  if(cookie == null)
  {
   return false;
  }
  else
  {
   return true;
  }
 }
 public static void setAttribute(String sid,String key,Object value)
 {
  //把置放入緩衝中
  MemSession session = MemSession.getSession(sid);
  session.setAttribute(key, value);
 }
 public static void setAttribute(HttpServletRequest request,String key,Object value)
 {
  Cookie cookie = RequestUtils.getCookie(request, "sid");
  if(cookie != null)
  {
//   取出session的ID
   String sid = cookie.getValue();
   //把置放入緩衝中
   MemSession session = MemSession.getSession(sid);
   session.setAttribute(key, value);
  }
 }
 public static Object getAttribute(String sid,String key)
 {
  //把置放入緩衝中
  MemSession session = MemSession.getSession(sid);
  return session.getAttribute(key); 
 }
 public static Object getAttribute(HttpServletRequest request,String key)
 {
  Cookie cookie = RequestUtils.getCookie(request, "sid");
 
  if(cookie != null)
  {
   //取出session的ID
   String sid = cookie.getValue();
   //把置放入緩衝中
   MemSession session = MemSession.getSession(sid);
   return session.getAttribute(key); 
  }
  return null;
 }
 public static void removeAttribute(HttpServletRequest request,String key)
 {
  Cookie cookie = RequestUtils.getCookie(request, "sid");
 
  if(cookie != null)
  {
   //取出session的ID
   String sid = cookie.getValue();
   //把置放入緩衝中
   MemSession session = MemSession.getSession(sid);
   session.removeAttribute(key);
  }
 
 }
 public static void invalidate(HttpServletRequest request)
 {
  Cookie cookie = RequestUtils.getCookie(request, "sid");
 
  if(cookie != null)
  {
   //取出session的ID
   String sid = cookie.getValue();
   //把置放入緩衝中
   MemSession session = MemSession.getSession(sid);
   session.invalidate();
  }
 }
 
}

//
登入
synchronized(訊號量)
{
 //驗證隱藏的驗證碼,同時刪除隨機驗證碼,避免重複登入
}

//1、此處先得到cookie中已有的會話ID,以便登入後清除memached中的會話資訊;

//2、清除前一個登入的會話資訊


String sid = java.util.UUID.randomUUID().toString()+serverName+"_"+userId;
//加入serverName,是為了區分多台伺服器產生的randomUUID可能相同

  com.util.RequestUtils.setCookie(request, response, "sid", sid, 30*60); 
  
  com.mem.session.SessionUtil.setAttribute(sid, "user_session_flag", userInfo);

 

//退出

刪除會話cookie同時刪除memcached中的會話資訊

com.mem.session.SessionUtil.invalidate(request);

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.