目的
session存储在缓存服务器上(各种缓存服务器上均可,本文以memcached为例),但对开发者来说,他不用关注,只需要调用request.getSession()方法即可获取到session,然后对session的属性进行操作。
面临的问题
1. session获取,不是从application的服务器上获取,要从memcached上获取。
2. session属性的获取及设置,不是设置到application服务器上,而是操作memcached获取或者设置。
解决问题的方法
1. 使用一个HttpServletRequestWrapper的实现类,重写getSession()方法,然后使用filter,来过滤每个请求,使request变为requestWrapper。
2. 使用一个HttpSessionAttributeListener的实现类,重写attributeAdded()、attributeRemoved()、attributeReplaced()方法,当属性发生改变时需要通知memcached中的session发生改变
另外:为解决各个异构系统因语言不通可能发生的兼容问题,session以json字符串存储。
具体代码如下:
wrapper类
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.http.HttpServletRequest;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.http.HttpServletRequestWrapper;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.http.HttpSession;
<span style="color: #0000ff;">import<span style="color: #000000;"> org.springframework.util.StringUtils;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.fasterxml.jackson.core.JsonParseException;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.fasterxml.jackson.databind.JsonMappingException;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.javacodegeeks.util.JacksonMapUtil;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.javacodegeeks.util.MemcachedUtil;
<span style="color: #0000ff;">public <span style="color: #0000ff;">class GetSessionWrapper <span style="color: #0000ff;">extends<span style="color: #000000;"> HttpServletRequestWrapper{
<span style="color: #0000ff;">private String sessionId=<span style="color: #0000ff;">null<span style="color: #000000;">;
<span style="color: #0000ff;">public<span style="color: #000000;"> GetSessionWrapper(HttpServletRequest request) {
<span style="color: #0000ff;">super<span style="color: #000000;">(request);
}
<span style="color: #0000ff;">public<span style="color: #000000;"> GetSessionWrapper(HttpServletRequest request,String sessionId) {
<span style="color: #0000ff;">super<span style="color: #000000;">(request);
<span style="color: #0000ff;">this<span style="color: #000000;">.setSessionId(sessionId);
}
@Override
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> HttpSession getSession() {
HttpSession httpSession</span>=<span style="color: #0000ff;">super</span><span style="color: #000000;">.getSession();
</span><span style="color: #008000;">//</span><span style="color: #008000;">id-->sessionId;</span>
String id="davidwang456"<span style="color: #000000;">;
String json</span>=<span style="color: #000000;">MemcachedUtil.getValue(id);
</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(StringUtils.isEmpty(json)){
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> httpSession;
}
httpSession.setAttribute(</span>"JPHPSESSID"<span style="color: #000000;">,id);
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 读取JSON数据</span>
Map<String,Object><span style="color: #000000;"> userData;
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
userData </span>= JacksonMapUtil.getMapper().readValue(json,Map.<span style="color: #0000ff;">class</span><span style="color: #000000;">);
</span><span style="color: #0000ff;">for</span>(Map.Entry<String,Object><span style="color: #000000;"> entry:userData.entrySet()){
httpSession.setAttribute(entry.getKey(),entry.getValue());
}
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (JsonParseException e) {
System.out.println(</span>"json字符串不能解析成功!"<span style="color: #000000;">);
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (JsonMappingException e) {
System.out.println(</span>"json字符串不能映射到Map!"<span style="color: #000000;">);
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (IOException e) {
System.out.println(</span>"io异常!"<span style="color: #000000;">);
}
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> httpSession;
}
@Override
</span><span style="color: #0000ff;">public</span> HttpSession getSession(<span style="color: #0000ff;">boolean</span><span style="color: #000000;"> create) {
HttpSession httpSession</span>=<span style="color: #0000ff;">super</span><span style="color: #000000;">.getSession(create);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> httpSession;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
String sessionId</span>="davidwang456"<span style="color: #000000;">;
String json</span>=<span style="color: #000000;">MemcachedUtil.getValue(sessionId);
System.out.println(json);
}
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String getSessionId() {
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> sessionId;
}
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> setSessionId(String sessionId) {
</span><span style="color: #0000ff;">this</span>.sessionId =<span style="color: #000000;"> sessionId;
}
}
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.FilterChain;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.FilterConfig;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.ServletException;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.ServletRequest;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.ServletResponse;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.http.Cookie;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.http.HttpServletRequest;
<span style="color: #0000ff;">import<span style="color: #000000;"> org.springframework.web.util.WebUtils;
<span style="color: #0000ff;">public <span style="color: #0000ff;">class FetchSession <span style="color: #0000ff;">implements<span style="color: #000000;"> javax.servlet.Filter{
<span style="color: #0000ff;">private <span style="color: #0000ff;">static <span style="color: #0000ff;">final String regex=".*(css|html|ico|html|jpg|jpeg|png|gif|js)"<span style="color: #000000;">;
@Override
<span style="color: #0000ff;">public <span style="color: #0000ff;">void init(FilterConfig filterConfig) <span style="color: #0000ff;">throws<span style="color: #000000;"> ServletException {
}
</span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> String getSessionId(ServletRequest request){
HttpServletRequest httpRequest</span>=<span style="color: #000000;">(HttpServletRequest)request;
String sessionId</span>=""<span style="color: #000000;">;
Cookie cookie </span>=WebUtils.getCookie(httpRequest,"PHPSESSID"<span style="color: #000000;">);
</span><span style="color: #0000ff;">if</span>(cookie!=<span style="color: #0000ff;">null</span><span style="color: #000000;">){
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> cookie.getValue();
}
cookie </span>=WebUtils.getCookie(httpRequest,"JSESSIONID"<span style="color: #000000;">);
</span><span style="color: #0000ff;">if</span>(cookie!=<span style="color: #0000ff;">null</span><span style="color: #000000;">){
sessionId</span>=<span style="color: #000000;"> cookie.getValue();
}
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> sessionId;
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> doFilter(ServletRequest request,ServletResponse response,FilterChain chain) </span><span style="color: #0000ff;">throws</span><span style="color: #000000;"> IOException,ServletException {
String sessionId</span>=<span style="color: #000000;">getSessionId(request);
HttpServletRequest httpRequest</span>=<span style="color: #000000;">(HttpServletRequest)request;
String requestedUri</span>=<span style="color: #000000;">httpRequest.getRequestURL().toString();
System.out.println(requestedUri);
</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(requestedUri.matches(regex)){
chain.doFilter(request,response);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;
}
GetSessionWrapper wrapperRequest</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> GetSessionWrapper(httpRequest,sessionId);
</span><span style="color: #008000;">//</span><span style="color: #008000;">HttpSession httpSession=wrapperRequest.getSession();</span>
<span style="color: #000000;"> chain.doFilter(wrapperRequest,response);
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> destroy() {
}
}
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.http.HttpSession;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.http.HttpSessionAttributeListener;
<span style="color: #0000ff;">import<span style="color: #000000;"> javax.servlet.http.HttpSessionBindingEvent;
<span style="color: #0000ff;">import<span style="color: #000000;"> org.springframework.util.StringUtils;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.fasterxml.jackson.core.JsonParseException;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.fasterxml.jackson.core.JsonProcessingException;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.fasterxml.jackson.databind.JsonMappingException;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.fasterxml.jackson.databind.ObjectMapper;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.javacodegeeks.util.JacksonMapUtil;
<span style="color: #0000ff;">import<span style="color: #000000;"> com.javacodegeeks.util.MemcachedUtil;
<span style="color: #0000ff;">public <span style="color: #0000ff;">class<span style="color: #000000;"> MySessionAttributeListener
<span style="color: #0000ff;">implements<span style="color: #000000;"> HttpSessionAttributeListener {
<span style="color: #0000ff;">private <span style="color: #0000ff;">static AtomicInteger count=<span style="color: #0000ff;">new AtomicInteger(0<span style="color: #000000;">);
<span style="color: #0000ff;">private <span style="color: #0000ff;">static AtomicInteger countU=<span style="color: #0000ff;">new AtomicInteger(0<span style="color: #000000;">);
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> attributeAdded(HttpSessionBindingEvent event) {
</span><span style="color: #0000ff;">int</span> ss=<span style="color: #000000;">count.incrementAndGet();
HttpSession session</span>=<span style="color: #000000;">event.getSession();
</span><span style="color: #008000;">//</span><span style="color: #008000;">String sessionId=(String) session.getAttribute("JPHPSESSID");</span>
String sessionId="davidwang456"<span style="color: #000000;">;
String attributeName </span>=<span style="color: #000000;"> event.getName();
Object attributeValue </span>=<span style="color: #000000;"> event.getValue();
System.out.println(</span>"Attribute add " + attributeName + " : " + attributeValue+",ss="+<span style="color: #000000;">ss);
String json</span>=<span style="color: #000000;">MemcachedUtil.getValue(sessionId);
</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(StringUtils.isEmpty(json)){
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ;
}
String json_new;
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
json_new </span>=<span style="color: #000000;"> attributeAddOrUpdate(json,attributeName,attributeValue);
MemcachedUtil.setValue(sessionId,json_new);
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
</span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO Auto-generated catch block</span>
<span style="color: #000000;"> e.printStackTrace();
}
}
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String attributeAddOrUpdate(String json,String key,Object value)
</span><span style="color: #0000ff;">throws</span><span style="color: #000000;"> JsonParseException,JsonMappingException,IOException{
ObjectMapper mapper</span>=<span style="color: #000000;">JacksonMapUtil.getMapper();
@SuppressWarnings(</span>"unchecked"<span style="color: #000000;">)
Map</span><String,Object> userData = mapper.readValue(json,Map.<span style="color: #0000ff;">class</span><span style="color: #000000;">);
Boolean flag</span>=String.<span style="color: #0000ff;">class</span><span style="color: #000000;">.isAssignableFrom(value.getClass());
</span><span style="color: #0000ff;">if</span>(!<span style="color: #000000;">flag){
Map</span><String,Object> map = mapper.convertValue(value,Map.<span style="color: #0000ff;">class</span><span style="color: #000000;">);
userData.putAll(map);
}</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{
userData.put(key,value);
}
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> mapper.writeValueAsString(userData);
}
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String attributeDel(String json,String key)
</span><span style="color: #0000ff;">throws</span><span style="color: #000000;"> JsonParseException,IOException {
ObjectMapper mapper </span>=<span style="color: #000000;"> JacksonMapUtil.getMapper();
@SuppressWarnings(</span>"unchecked"<span style="color: #000000;">)
Map</span><String,Map.<span style="color: #0000ff;">class</span><span style="color: #000000;">);
userData.remove(key);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> mapper.writeValueAsString(userData);
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> attributeRemoved(HttpSessionBindingEvent event) {
HttpSession session</span>=<span style="color: #000000;">event.getSession();
</span><span style="color: #008000;">//</span><span style="color: #008000;">String sessionId=(String) session.getAttribute("JPHPSESSID");</span>
String sessionId="davidwang456"<span style="color: #000000;">;
String attributeName </span>=<span style="color: #000000;"> event.getName();
System.out.println(</span>"Attribute del : " +<span style="color: #000000;"> attributeName);
String json</span>=<span style="color: #000000;">MemcachedUtil.getValue(sessionId);
</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(StringUtils.isEmpty(json)){
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ;
}
String json_new;
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
json_new </span>=<span style="color: #000000;"> attributeDel(json,attributeName);
MemcachedUtil.setValue(sessionId,json_new);
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
</span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO Auto-generated catch block</span>
<span style="color: #000000;"> e.printStackTrace();
}
}
@Override
</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> attributeReplaced(HttpSessionBindingEvent event) {
</span><span style="color: #0000ff;">int</span> ssu=<span style="color: #000000;">countU.incrementAndGet();
HttpSession session</span>=<span style="color: #000000;">event.getSession();
</span><span style="color: #008000;">//</span><span style="color: #008000;">String sessionId=(String) session.getAttribute("JPHPSESSID");</span>
String sessionId="davidwang456"<span style="color: #000000;">;
String attributeName </span>=<span style="color: #000000;"> event.getName();
Object attributeValue </span>=<span style="color: #000000;"> event.getValue();
System.out.println(</span>"Attribute update " + attributeName + " : " + attributeValue+",ss="+<span style="color: #000000;">ssu);
String json</span>=<span style="color: #000000;">MemcachedUtil.getValue(sessionId);
</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(StringUtils.isEmpty(json)){
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ;
}
String json_new;
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
json_new </span>=<span style="color: #000000;"> attributeAddOrUpdate(json,json_new);
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
</span><span style="color: #008000;">//</span><span style="color: #008000;"> TODO Auto-generated catch block</span>
<span style="color: #000000;"> e.printStackTrace();
}
}
}
com.fasterxml.jackson.core
jackson-databind
2.4.3
com.fasterxml.jackson.core
jackson-annotations
2.4.3
com.fasterxml.jackson.datatype
jackson-datatype-guava
2.4.3
com.fasterxml.jackson.datatype
jackson-datatype-joda
2.4.3
com.fasterxml.jackson.datatype
jackson-datatype-jsr310
2.4.3
net.spy
spymemcached
2.12.0
注意:上面代码仅为demo代码,实际应用需重构代码。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|