1:原理图
2代码实现
1)接口代码
package cn.zhou.common.web.session;
import java.io.Serializable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* session供应类
* @author Administrator
*
*/
public interface SessionProvider {
//往Session设置值
//name Constants buyer_session
//value 用户对象 Serializable value 是对象序列化,用于远程session
public void setAttribute(HttpServletRequest request, String name,Serializable value,HttpServletResponse response);
//从Session中取值
public Serializable getAttribute(HttpServletRequest request,String name,HttpServletResponse response);
//退出登陆
public void logout(HttpServletRequest request,HttpServletResponse response);
//获取SessionID
public String getSessionId(HttpServletRequest request,HttpServletResponse response);
}
2)实现代码
package cn.zhou.common.web.session;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import com.danga.MemCached.MemCachedClient;
/**
* 远程Session
* 存放在Memcached缓存服务器里的Session
* @author lx
*
*/
public class CacheSessionProvider implements SessionProvider {
@Autowired
private MemCachedClient memCachedClient;
private final String SESSIONID="sessionId";
//设置数据保存在memcached的保存时间
private final Integer expiry=30*60;
/**
* 将session的值通过sessionId值存入memcached中
*/
public void setAttribute(HttpServletRequest request, String name, Serializable value,HttpServletResponse response) {
// TODO Auto-generated method stub
Map<String, Serializable> session=new HashMap<String, Serializable>();
session.put(name, value);
String sessionId=getSessionId(request, response);
memCachedClient.set(sessionId, session, expiry);
}
/**
* 通过用户本地的sessionId值到服务器获取session
* 从缓存服务器memcached中获取sessionId值对应的session
*/
public Serializable getAttribute(HttpServletRequest request, String name,HttpServletResponse response) {
// TODO Auto-generated method stub
String sessionId=getSessionId(request, response);
Map<String, Serializable> session = (Map<String, Serializable>)memCachedClient.get(sessionId);
//返回保存在session中的用户数据
if(session!=null){
return session.get(name);
}
return null;
}
/**
*
* 删除缓存服务器memcached中中key=sessionId,这样用户即使
* 通过本地的sessionID也获取不到用户的数据
*/
public void logout(HttpServletRequest request,HttpServletResponse response) {
// TODO Auto-generated method stub
//用户本地cookie
String sessionId=getSessionId(request, response);
if(memCachedClient.keyExists(sessionId)){
memCachedClient.delete(sessionId);
}
}
/**
* 获取sessionId,如果用户没有sessionId,则为用户创建一个sessionId
*/
public String getSessionId(HttpServletRequest request,HttpServletResponse response) {
//获取存储在cookie的sessionId
Cookie[] cookies = request.getCookies();
if(cookies!=null && cookies.length>0){
for (Cookie cookie : cookies) {
if(SESSIONID.equals(cookie.getName())){
return cookie.getValue();
}
}
}
//如果没有sessionId,为用户创建一个
String sessionId=UUID.randomUUID().toString().replaceAll("-", "");
Cookie cookie=new Cookie(SESSIONID, sessionId);
cookie.setMaxAge(-1);// 默认-1,代表关闭浏览器就销毁cookie
cookie.setPath("/");
response.addCookie(cookie);
return sessionId;
}
}
3)本地实现代码,该代码只用于项目还没有发布上去,没有实现session共享,开发自己用的本地session
session共享实现代码与本地session代码共同实现同一个接口,目的是为了未来需要将本地session改为session共享的实现代码,bean那边接口名不需要改,只要改实现类,这样注解 session 接口 实例化就是session共享的对象。