SpringMVC:学习笔记(12)——ThreadLocal实现会话共享
SpringMVC:学习笔记(12)——ThreadLocal实现会话共享
ThreadLocal
ThreadLocal,被称为线程局部变量。在并发编程的情况下,使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。每个Thread对象内部都维护了一个ThreadLocalMap它可以存放若干个ThreadLocal。如下为Thread源码部分:
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
当我们对ThreadLocal执行set方法时,他首先做的是取当前线程的ThreadLocalMap,所以可以保证每个线程可以独享自己的ThreadLocal对象。如下为ThreadLocal源码部分:
/**
* Sets the current thread's copy of this thread-local variable
* to the specified value. Most subclasses will have no need to
* override this method, relying solely on the {@link #initialValue}
* method to set the values of thread-locals.
*
* @param value the value to be stored in the current thread's copy of
* this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
那这样一来ThreadLocal就具有了一些高级特性:
- 全局性,在当前线程中,任何一个点都可以访问到ThreadLocal的值。
- 独立性,该线程的ThreadLocal只能被该线程访问,一般情况下其他线程访问不到。
实现会话共享
通用的思路
在SpringMVC中,@Action方法接受了Request对象,我们可以从中取出HttpSession会话数据
public ModelAndView getTest(HttpServletRequest request, HttpServletResponse response){
String userId = request.getSession().getAttribute("user").toString();
}
但要是我们在一个普通的方法中想访问到HttpSession对象就会很难了,如果我们在请求到来时用Filter把HttpSession保存到ThreadLocal中,利用ThreadLocal的全局性,不是就可以在普通方法中使用了吗?当然我们最好将其封装一个类,来方便以后随时调用和迭代更新。
HttpContext
我们创建一个HttpContext类,来将Request、Response、Session、Cookies等对象进行封装,方便以后直接使用。
public class HttpContext {
private HttpServletRequest request;
private HttpServletResponse response;
private final static ThreadLocal<HttpContext> contextContainer = new ThreadLocal<HttpContext>();
/**
* 初始化
*/
public static HttpContext begin(HttpServletRequest req, HttpServletResponse res) {
HttpContext context = new HttpContext();
context.request = req;
context.response = res;
contextContainer.set(context);
return context;
}
public static HttpContext get(){
return contextContainer.get();
}
/**
* 销毁
*/
public void end() {
this.request = null;
this.response = null;
contextContainer.remove();
}
public ServletContext getContext() {
return this.request.getServletContext();
}
public HttpSession getSession() {
return this.request.getSession(false);
}
public HttpServletRequest getRequest() {
return this.request;
}
public HttpServletResponse getResponse() {
return this.response;
}
public Map<String, Cookie> getCookies() {
Map<String, Cookie> map = new HashMap<String, Cookie>();
Cookie[] cookies = this.request.getCookies();
if(cookies != null)
for(Cookie ck : cookies) {
map.put(ck.getName(), ck);
}
return map;
}
}
WebFilter
过滤器是实现会话共享的前提,我们在里面只是绑定一下请求对象。
/**
* HttpContext全局过滤器
*/
public class ContextFilter implements Filter{
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)servletRequest;
HttpServletResponse res = (HttpServletResponse)servletResponse;
HttpContext.begin(req, res);
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
HttpContext.get().end();
}
}
使用
现在,我们可以在一个普通的Java方法中,使用会话对象,如果我们做一个简单的Dispatcher,然后使用Response对象,那么一个后端框架便横空出世了!
/**
* 获得当前登录人员的凭证信息
*/
public static String getId(){
HttpSession session = HttpContext.get().getSession();
Object obj = null;
if (null != session){
obj = session.getAttribute("USERID");
}
if (null == obj) {
return null;
}
return obj.toString();
}
参考链接
http://www.blackzs.com/archives/740
SpringMVC:学习笔记(12)——ThreadLocal实现会话共享的更多相关文章
- springmvc学习笔记(12)-springmvc注解开发之包装类型參数绑定
springmvc学习笔记(12)-springmvc注解开发之包装类型參数绑定 标签: springmvc springmvc学习笔记12-springmvc注解开发之包装类型參数绑定 需求 实现方 ...
- Qt学习笔记12:基本会话框4——总结
文件对话框静态函数 QString QFileDialog::getOpenFileName{ QWidget *parent = 0; //标准文件对话框的父窗口 const QString &am ...
- Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建
Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...
- SpringMVC学习笔记之二(SpringMVC高级参数绑定)
一.高级参数绑定 1.1 绑定数组 需求:在商品列表页面选中多个商品,然后删除. 需求分析:功能要求商品列表页面中的每个商品前有一个checkbok,选中多个商品后点击删除按钮把商品id传递给Cont ...
- 并发编程学习笔记(8)----ThreadLocal的使用及源码分析
1. ThreadLocal的理解 ThreadLocal,顾名思义,就是线程的本地变量,ThreadLocal会为每个线程创建一个本地变量副本,使得使用ThreadLocal管理的变量在多线程的环境 ...
- springmvc学习笔记(10)-springmvc注解开发之商品改动功能
springmvc学习笔记(10)-springmvc注解开发之商品改动功能 标签: springmvc springmvc学习笔记10-springmvc注解开发之商品改动功能 需求 开发mappe ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
- 史上最全的SpringMVC学习笔记
SpringMVC学习笔记---- 一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于Spring ...
- springmvc学习笔记--REST API的异常处理
前言: 最近使用springmvc写了不少rest api, 觉得真是一个好框架. 之前描述的几篇关于rest api的文章, 其实还是不够完善. 比如当遇到参数缺失, 类型不匹配的情况时, 直接抛出 ...
随机推荐
- Kubernetes 学习22 kubernetes容器资源需求资源限制及HeapSter(翻车章节)
一.概述 1.接下来介绍在k8s上运行pod对象时我们如何去监控我们系统级的资源指标以及业务级别的资源指标.数据如何获取和监控.在此之前先介绍一下Pod对象的资源请求和资源限制.即容器的资源需求和资源 ...
- Windows下串口编程
造冰箱的大熊猫@cnblogs 2019/1/27 将Windows下串口编程相关信息进行下简单小结,以备后用. 1.打开串口 打开串口使用CreateFile()函数.以打开COM6为例: HAN ...
- zabbix基本介绍
来源是 觅安教育 大家有兴趣可以去哔哩哔哩搜搜. Open-falcon是由小米公司开源 比如windows,linux,unix,openBSD,AIX,solaris,Mac等操作系统,都可以安装 ...
- linux管道pipe详解
linux管道pipe详解 https://blog.csdn.net/qq_42914528/article/details/82023408
- ZR#1004
ZR#1004 解法: 对于 $ (x^2 + y)^2 \equiv (x^2 - y)^2 + 1 \pmod p $ 化简并整理得 $ 4x^2y \equiv 1 \pmod p $ 即 $ ...
- [转] 修改sqlserver的数据库名、物理名称和逻辑文件名
转载: https://blog.csdn.net/dym0080/article/details/81017777
- 基于Redis的分布式锁到底安全吗(上)?
基于Redis的分布式锁到底安全吗(上)? 2017-02-11 网上有关Redis分布式锁的文章可谓多如牛毛了,不信的话你可以拿关键词“Redis 分布式锁”随便到哪个搜索引擎上去搜索一下就知道了 ...
- 为 Raft 引入 leader lease 机制解决集群脑裂时的 stale read 问题
问题:当 raft group 发生脑裂的情况下,老的 raft leader 可能在一段时间内并不知道新的 leader 已经被选举出来,这时候客户端在老的 leader 上可能会读取出陈旧的数据( ...
- HttpWebRequest Timeout
随着REST风格的流行,直接通过 HttpWebRequest 进行服务调用的客户端应用越来越多.这里总结一些可能需要费时调查的经验,希望能帮助大家. 1. 用完的HttpWebRequest要Abo ...
- 数据结构---哈希表的C语言实现(闭散列)
原文地址:https://blog.csdn.net/weixin_40331034/article/details/79461705 构造一种存储结构,通过某种函数(hashFunc)使元素的存储位 ...