目的

  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类

import java.io.IOException;
import java.util.Map;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;import org.springframework.util.StringUtils;import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.javacodegeeks.util.JacksonMapUtil;
import com.javacodegeeks.util.MemcachedUtil;public class GetSessionWrapper extends HttpServletRequestWrapper{private String sessionId=null;public GetSessionWrapper(HttpServletRequest request) {super(request);}public GetSessionWrapper(HttpServletRequest request,String sessionId) {super(request);this.setSessionId(sessionId);}@Overridepublic HttpSession getSession() {HttpSession httpSession=super.getSession();//id-->sessionId;String id="davidwang456";String json=MemcachedUtil.getValue(id);if(StringUtils.isEmpty(json)){return httpSession;}httpSession.setAttribute("JPHPSESSID", id);// 读取JSON数据Map<String, Object> userData;try {userData = JacksonMapUtil.getMapper().readValue(json, Map.class);for(Map.Entry<String, Object> entry:userData.entrySet()){ httpSession.setAttribute(entry.getKey(), entry.getValue());    } } catch (JsonParseException e) {System.out.println("json字符串不能解析成功!");} catch (JsonMappingException e) {System.out.println("json字符串不能映射到Map!");} catch (IOException e) {System.out.println("io异常!");}return httpSession;}@Overridepublic HttpSession getSession(boolean create) {HttpSession httpSession=super.getSession(create);return httpSession;        }public static void main(String[] args) {String sessionId="davidwang456";String json=MemcachedUtil.getValue(sessionId);System.out.println(json);}public String getSessionId() {return sessionId;}public void setSessionId(String sessionId) {this.sessionId = sessionId;}
}

filter类

import java.io.IOException;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.HttpServletRequest;import org.springframework.web.util.WebUtils;public class FetchSession implements javax.servlet.Filter{private static final String regex=".*(css|html|ico|html|jpg|jpeg|png|gif|js)";@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}private static String getSessionId(ServletRequest request){HttpServletRequest httpRequest=(HttpServletRequest)request;String sessionId="";Cookie cookie =WebUtils.getCookie(httpRequest, "PHPSESSID");if(cookie!=null){return cookie.getValue();}cookie =WebUtils.getCookie(httpRequest, "JSESSIONID");if(cookie!=null){sessionId= cookie.getValue();}return sessionId;}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {String sessionId=getSessionId(request);HttpServletRequest httpRequest=(HttpServletRequest)request;    String requestedUri=httpRequest.getRequestURL().toString();System.out.println(requestedUri);if(requestedUri.matches(regex)){chain.doFilter(request, response);return;}GetSessionWrapper wrapperRequest=new GetSessionWrapper(httpRequest,sessionId);//HttpSession httpSession=wrapperRequest.getSession();
            chain.doFilter(wrapperRequest, response);        }@Overridepublic void destroy() {}
}

属性监听器

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);@Overridepublic 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);}@Overridepublic 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();}}@Overridepublic 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();}}}

pom.xml依赖:

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.4.3</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.4.3</version></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-guava</artifactId><version>2.4.3</version></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-joda</artifactId><version>2.4.3</version></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId><version>2.4.3</version></dependency><dependency><groupId>net.spy</groupId><artifactId>spymemcached</artifactId><version>2.12.0</version></dependency>

注意:上面代码仅为demo代码,实际应用需重构代码。

转载于:https://www.cnblogs.com/davidwang456/p/5256874.html

简单的session共享的封装相关推荐

  1. 使用Shiro+Redis实现Session共享

    章节目录 1. 为什么要实现Session共享? 1.1 负载均衡 1.2 负载均衡中的Session问题 1.3 案例演示 2. Shiro架构 3. Shiro集成Redis 1. 为什么要实现S ...

  2. SpringBoot一个依赖搞定Session共享,没有比这更简单的方案了!

    作者:江南一点雨 微信公众号:牧码小子(ID:a_javaboy) 上一篇:推荐10个你不得不关注的NB技术公众号 有的人可能会觉得题目有点夸张,其实不夸张,题目没有使用任何修辞手法!认真读完本文,你 ...

  3. Spring Boot 一个依赖搞定 session 共享,没有比这更简单的方案了!

    有的人可能会觉得题目有点夸张,其实不夸张,题目没有使用任何修辞手法!认真读完本文,你就知道gblfy说的是对的了! 文章目录 一.背景 二.分析思路 三.实战 1. 创建工程 2. pom.xml 3 ...

  4. session共享的另外一篇博客.好文章

    搬运地址:https://www.cnblogs.com/newP/p/6518918.html Session分布式共享 = Session + Redis + Nginx 一.Session 1. ...

  5. Tomcat集群通过redis实现session共享

    Tomcat集群通过redis实现session共享 最近在XXX项目上做了tomcat集群的session共享,闲来无事鄙人将整个踩坑的过程粗糙的记录下来,给同学们分享一波,整个过程无硬编码,爽歪歪 ...

  6. 分布式中使用 Redis 实现 Session 共享(中)

    http://blog.jobbole.com/91874/ 原文出处: 焰尾迭   欢迎分享原创到伯乐头条 上一篇介绍了一些redis的安装及使用步骤,本篇开始将介绍redis的实际应用场景,先从最 ...

  7. Springboot整合springsession实现session共享

    Springboot整合springsession实现session共享 简介 session我们之前有介绍过(可见springboot整合springsecurity),简单来说就是将用户信息或者数 ...

  8. session共享问题

    一.session会话机制 由于http 协议的特性是无状态性 ,http 协议本身是无状态的,客户端只需要向服务器请求下载某些文件,无论是客户端还是服务器都没必要记录彼此过去的行为,每一次请求之间对 ...

  9. Spring Session Redis实现Session共享

    Spring Session & Redis实现Session共享 前后端分离Session.单点登录实现 Session 共享简单方案,充当笔记 一.Session和Cookie 1.Ses ...

最新文章

  1. JAVA ssm b2b2c多用户商城系统源码 (十二)springboot集成apidoc
  2. Win2008R2配置WebDeploy发布网站
  3. linux c 打印错误信息error errno perror和strerror的区别
  4. R语言编程基础(2)
  5. 永州计算机应用等级,5月永州计算机应用能力考试报名
  6. python如何检查错误-python中的错误如何查看
  7. 拉格朗日中值定理ξ怎么求_高等数学3.1中值定理
  8. 2015级C++第7周项目 友元、共享数据保护、多文件结构
  9. msvcrtd.lib(crtexew.obj):error LNK2019:无法解析的外部符号WinMain@16,该符号在函数___tmainCRTStartup中被引用
  10. day03_雷神_文件操作
  11. Japanese(Shift-Jis)的编码范围
  12. turtle绘制五角星
  13. 2019年最新出搜索引擎蜘蛛网页爬虫大全
  14. 4K Stogram Mac版(Instagram照片下载工具)中文版
  15. Netty框架之责任链模式及其应用
  16. 致铭主板好礼等着您拿
  17. 自学B站小甲鱼数据结构课程-C语言实现基础数据结构-栈-的例子
  18. 来了!新一代 App 视觉增强辅助方案它真的来了!
  19. Word中单倍行间距是多少磅
  20. mac苹果灯亮出风口烫开不了机解决办法

热门文章

  1. npoi生成的表格数字左上角_如何用openpyxl自动化编写Excel电子表格 进阶篇 下
  2. lucene python_Python下的Lucene,PyLucene
  3. linux软件升级直接替换,Linux几个命令的升级替代品
  4. ai怎么画循环曲线,怎么用 Adobe Illustrator 画出曲率连续的曲线?
  5. angular5绑定html,在Angular模板绑定中剥离html
  6. oracle12c默认字符集,修改Oracle【12C】字符集
  7. AppWidgetServiceImpl: Widget Error: widget.host.callbacks is null
  8. java lambda collect_45分钟学会Java8 - Lambda和Stream
  9. C++输入输出类的层次
  10. java 自定义arraylist_Java 中模仿源码自定义ArrayList