主流的session共享方案:将session统一存储在内存数据库redis或memcached或soler或其他,
面临的问题
1. session获取,不是从application的服务器上获取,要从memcached上获取。
2. session属性的获取及设置,不是设置到application服务器上,而是操作memcached获取或者设置。
解决问题的方法
重写获取session方法:1. 使用一个HttpServletRequestWrapper(HttpServletRequest的装饰类)的实现类,重写getSession()方法,然后使用filter,来过滤每个请求,使request变为requestWrapper。
面临的问题
1. session获取,不是从application的服务器上获取,要从memcached上获取。
2. session属性的获取及设置,不是设置到application服务器上,而是操作memcached获取或者设置。
解决问题的方法
重写获取session方法:1. 使用一个HttpServletRequestWrapper(HttpServletRequest的装饰类)的实现类,重写getSession()方法,然后使用filter,来过滤每个请求,使request变为requestWrapper。
重写设置session键值的方法:2. 使用一个HttpSessionAttributeListener的实现类,重写attributeAdded()、attributeRemoved()、attributeReplaced()方法,当属性发生改变时需要通知memcached中的session发生改变
详细代码:
属性监听器:
import java.io.IOException; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; import org.springframework.util.StringUtils; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.javacodegeeks.util.JacksonMapUtil; import com.javacodegeeks.util.MemcachedUtil; public class MySessionAttributeListener implements HttpSessionAttributeListener { private static AtomicInteger count=new AtomicInteger(0); private static AtomicInteger countU=new AtomicInteger(0); @Override public void attributeAdded(HttpSessionBindingEvent event) { int ss=count.incrementAndGet(); HttpSession session=event.getSession(); //String sessionId=(String) session.getAttribute("JPHPSESSID"); String sessionId="davidwang456"; String attributeName = event.getName(); Object attributeValue = event.getValue(); System.out.println("Attribute add " + attributeName + " : " + attributeValue+",ss="+ss); String json=MemcachedUtil.getValue(sessionId); if(StringUtils.isEmpty(json)){ return ; } String json_new; try { json_new = attributeAddOrUpdate(json,attributeName,attributeValue); MemcachedUtil.setValue(sessionId, json_new); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private String attributeAddOrUpdate(String json,String key,Object value) throws JsonParseException, JsonMappingException, IOException{ ObjectMapper mapper=JacksonMapUtil.getMapper(); @SuppressWarnings("unchecked") Map<String,Object> userData = mapper.readValue(json, Map.class); Boolean flag=String.class.isAssignableFrom(value.getClass()); if(!flag){ Map<String, Object> map = mapper.convertValue(value, Map.class); userData.putAll(map); }else{ userData.put(key, value); } return mapper.writeValueAsString(userData); } private String attributeDel(String json, String key) throws JsonParseException, JsonMappingException, IOException { ObjectMapper mapper = JacksonMapUtil.getMapper(); @SuppressWarnings("unchecked") Map<String, Object> userData = mapper.readValue(json, Map.class); userData.remove(key); return mapper.writeValueAsString(userData); } @Override public void attributeRemoved(HttpSessionBindingEvent event) { HttpSession session=event.getSession(); //String sessionId=(String) session.getAttribute("JPHPSESSID"); String sessionId="davidwang456"; String attributeName = event.getName(); System.out.println("Attribute del : " + attributeName); String json=MemcachedUtil.getValue(sessionId); if(StringUtils.isEmpty(json)){ return ; } String json_new; try { json_new = attributeDel(json,attributeName); MemcachedUtil.setValue(sessionId, json_new); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void attributeReplaced(HttpSessionBindingEvent event) { int ssu=countU.incrementAndGet(); HttpSession session=event.getSession(); //String sessionId=(String) session.getAttribute("JPHPSESSID"); String sessionId="davidwang456"; String attributeName = event.getName(); Object attributeValue = event.getValue(); System.out.println("Attribute update " + attributeName + " : " + attributeValue+",ss="+ssu); String json=MemcachedUtil.getValue(sessionId); if(StringUtils.isEmpty(json)){ return ; } String json_new; try { json_new = attributeAddOrUpdate(json,attributeName,attributeValue); MemcachedUtil.setValue(sessionId, json_new); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }