博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
改用ServletRequestAttributes
阅读量:6599 次
发布时间:2019-06-24

本文共 2101 字,大约阅读时间需要 7 分钟。

title: 改用ServletRequestAttributes date: 2017.05.27 02:29 categories:

  • 技术博客 tags:
  • 实现方式
  • Spring

想要拿到当前线程中的请求,直接在工具类中放了个ThreadLocal作为容器,当时候的需求只需要拿到request即可,所以那个方式是可以的。

但现在不一样了,我们在做的这个系统中需要更多的东西,比如会把用户对象放到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类是无法方便操作requestsession这些原生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
requestAttributesHolder = new NamedThreadLocal
("Request attributes");public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }复制代码

当然在逻辑上,它会判断参数是否为空、是否为可继承的等等等等。

小结

因此你也看到了,出现新的需求都是找得到解决方案的,顺便看了下源码,加深了一些印象跟理解。这时候可能过程比结果重要。

转载于:https://juejin.im/post/5a311ce051882575cb741b1e

你可能感兴趣的文章
深醒科技人脸识别速度可达每秒30亿次,2秒即可比对全球人脸
查看>>
区块链每日一问丨区块链技术中的“分布式账簿”是什么?它有什么优势?
查看>>
Mozart Update 2(7008)
查看>>
java8 Optional正确使用姿势
查看>>
为.NET部署应用程序添加个卸载程序
查看>>
linux之Find命令总结
查看>>
nginx泛解析域名实现多级域名多个域名跳转
查看>>
Windows程序以特定用户身份运行
查看>>
.NET下获取网页的内容的封装类
查看>>
用tl进行图片增强
查看>>
网络工程师必备的好帮手usb转console调试线
查看>>
mmJ:Linux强制更新Ip地址,解决Ip冲突无法访问问题
查看>>
大数据|java API写入HDFS文件-put
查看>>
CENTOS7.2使用RDO方式安装OpenStack Mitaka笔记
查看>>
nginx [emerg] socket() []80 failed (97 Address family not supported by protocol)
查看>>
java:泛型|元组类库
查看>>
Linux网络管理(二)
查看>>
oracle存储过程的简单学习1
查看>>
SSH免密码登录实现
查看>>
Linux自学笔记——文件共享服务之ftp
查看>>