ServletRequestAttributes用法详解——Spring系列学习笔记
之前想要拿到当前线程中的请求,直接在工具类中放了个ThreadLocal作为容器,当时候的需求只需要拿到request即可,所以那个方式是可以的。
关于ThreadLocal相关知识,可以参考我的这篇博文——>https://zhanglong.blog.csdn.net/article/details/120698432
但现在不一样了,我们在做的这个系统中需要更多的东西,比如会把用户对象放到session中,在判断是否为当前用户这种情况下就比较常用,那之前的代码就不太适合了,因为作为容器的ThreadLocal中只能将request作为参数set进去,session是进不去的。
一种解决方案是修改工具类中的容器,改用RequestContextHolder中的ServletRequestAttributes来存放「用于存放用户信息的session」。
改进后的代码:
public static HttpSession getSession(){ServletRequestAttributes ra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = ra.getRequest();HttpSession session = request.getSession();return session;}
1. RequestContextHolder类
文档描述:
Holder class to expose the web request in the form of a thread-bound RequestAttributes object.,简单翻译下,这个类的作用是通过操作RequestAttributes请求属性这个对象(绑定了线程)来间接处理请求相关的一些东西。
所以你可以看到代码中首先拿到了RequestAttributes对象,当然这里要转成Servlet类型。
2. ServletRequestAttributes类
如果不转型,那个attributes类是无法方便操作request、session这些原生servlet相关的对象或者属性的,因为本身Java Web最原始的实现就是servlet形式的,Spring框架当然会为其做特定的一些封装,也就是这个类的来源。
代码中首先通过属性拿到了HttpServletRequest对象,然后通过请求对象拿到session。
这里有个小问题,那就是既然里面已经有一个getSession(boolean allowCreate)方法了,那为啥不直接获取session对象呢?
我简单回去看了下源码,这个方法上带了一个布尔类型的参数,含义是是否允许创建session,在方法逻辑内部也调用了这个方法,然后也会发现在对于attribute的操作方法,如setAttribute+removeAttribute+getAttributeNames+updateAccessedSessionAttributes中都调用了getSession,然后根据不同的逻辑传入true或者false,也就是说,这个getSessioin本身不是为我们所写,它的存在是为了完善这一套的逻辑,建立起请求、回话、属性之间的前后逻辑。所以我们不直接调用它,因为你不知道该传true还是false。
3. NamedThreadLocal
最后一个关键点就是,RequestContextHolder如何绑定线程,说白了,它也是组合了ThreadLocal,在setAttribute中本质上也是把value放到ThreadLocalMap中,相关源码如下:
private static final ThreadLocal<RequestAttributes> requestAttributesHolder =new NamedThreadLocal<RequestAttributes>("Request attributes");
public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);}
复制代码当然在逻辑上,它会判断参数是否为空、是否为可继承的等等等等。
4. 小结
因此你也看到了,出现新的需求都是找得到解决方案的,顺便看了下源码,加深了一些印象跟理解。这时候可能过程比结果重要。
ServletRequestAttributes用法详解——Spring系列学习笔记相关推荐
- spring RestTemplate用法详解
spring RestTemplate用法详解 spring 3.2.3 框架参考有说明 21.9 Accessing RESTful services on the Client 转载于:https ...
- Ext.Net学习笔记22:Ext.Net Tree 用法详解
上面的图片是一个简单的树,使用Ext.Net来创建这样的树结构非常简单,代码如下: <ext:TreePanel runat="server"><Root> ...
- spring boot模板引擎thymleaf用法详解
spring boot模板引擎thymleaf用法详解 Spring-boot支持FreeMarker.Thymeleaf.jsp.veocity 但是对freemarker和thymeleaf的支持 ...
- linux getline函数用法,Linux文本处理三剑客之awk学习笔记05:getline用法详解
getline用法详解 在默认情况下,awk支持从文件或者STDIN中读取数据.我们也可以使用getline来灵活读取数据,例如在main代码块执行过程中读取某个非待处理文件的数据,或者从某个读取某个 ...
- 《算法笔记》学习日记——6.1 vector的常见用法详解
目录 6.1 vector的常见用法详解 问题 A: Course List for Student (25) 问题 B: Student List for Course (25) 小结 6.1 ve ...
- Python中self用法详解
Python中self用法详解 https://blog.csdn.net/CLHugh/article/details/75000104 首页 博客 学院 下载 图文课 论坛 APP 问答 商城 V ...
- java配置文件实现方式_java相关:详解Spring加载Properties配置文件的四种方式
java相关:详解Spring加载Properties配置文件的四种方式 发布于 2020-4-29| 复制链接 摘记: 一.通过 context:property-placeholder 标签实现配 ...
- php theme_path,PHP_Yii2主题(Theme)用法详解,本文实例讲述了Yii2主题(Theme) - phpStudy
Yii2主题(Theme)用法详解 本文实例讲述了Yii2主题(Theme)用法.分享给大家供大家参考,具体如下: 首先看看主要的配置方式: 'components' => [ 'view' = ...
- PowerShell攻防进阶篇:nishang工具用法详解
PowerShell攻防进阶篇:nishang工具用法详解 导语:nishang,PowerShell下并肩Empire,Powersploit的神器. 开始之前,先放出个下载地址! 下载地址:htt ...
最新文章
- C中常用字符串处理函数
- 用递归合并两个排序的链表
- jquery让页面滚动到底部
- Loj#6039-「雅礼集训 2017 Day5」珠宝【四边形不等式,dp】
- python怎么换行继续写脚本_python怎么换行继续写脚本
- CGI与JSP联系与区别
- Java 实验五 王奕开
- Affymetrix基因芯片小总结
- js获取引用的css样式,js获取css样式方法
- secoclient免积分下载
- OpenCASCADE VS2010 SP1编译
- unity 画球面_Unity实现球面行走
- 写好一份数据分析报告需要注意的13个要点
- 2012, PPSN,Geometric Semantic Genetic Programming,GSGP
- cocos恭喜喜庆粒子特效
- win10桌面文件丢失的处理总结
- 【工具-AWVS】AWVS安装与使用
- 学习笔记:C++进阶【继承、多态、二叉树进阶、map和set、哈希、C++11、异常、智能指针、特殊类设计、C++的类型转换】
- 思维导图的分类 利用思维导图绘制学习知识方法介绍
- 【Java基础】Java入门(一)