Spring MVC中获取Request的方法及分析
一、概述
在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对象,比如获取客户端IP地址、请求的URL、header中的属性(如cookie、授权信息)、body中的数据等。由于在Spring MVC中,处理请求的Controller、Service等对象都是单例的,因此获取request对象时最需要注意的问题,便是request对象是否是线程安全的:当有大量并发请求时,能否保证不同请求/线程中使用不同的request对象。
这里还有一个问题需要注意:前面所说的“在处理请求时”使用request对象,究竟是在哪里使用呢?考虑到获取request对象的方法有微小的不同,大体可以分为两类:
1、在Spring的Bean中使用request对象:既包括Controller、Service、Repository等MVC的Bean,也包括了Component等普通的Spring Bean。为了方便说明,后文中Spring中的Bean一律简称为Bean。
2、在非Bean中使用request对象:如普通的Java对象的方法中使用,或在类的静态方法中使用。
此外,本文讨论是围绕代表请求的request对象展开的,但所用方法同样适用于response对象、InputStream/Reader、OutputStream/ Writer等;其中InputStream/Reader可以读取请求中的数据,OutputStream/Writer可以向响应写入数据。
二、获取request方法
1、controller中加参数
该方法实现的原理是,在Controller方法开始处理请求时,Spring会将request对象赋值到方法参数中。除了request对象,可以通过这种方法获取的参数还有很多,比如response。Controller中获取request对象后,如果要在其他方法中(如service方法、工具类方法等)使用request对象,需要在调用这些方法时将request对象作为参数传入。
安全性:此时request对象是方法参数,相当于局部变量,毫无疑问是线程安全的
优缺点:(1)如果多个controller方法中都需要request对象,那么在每个方法中都需要添加一遍request参数,冗余太多
(2)request对象的获取只能从controller开始,如果使用request对象的地方在函数调用层级比较深的地方,那么整个调用链上的所有方法都需要添加request参数。实际上,在整个请求处理的过程中,request对象是贯穿始终的;也就是说,除了定时器等特殊情况,request对象相当于线程内部的一个全局变量。而该方法,相当于将这个全局变量,传来传去。
2、自动注入方式
@Autowired
private HttpServletRequest request;
安全性:Controller的scope是singleton(单例),也就是说在整个web系统中,只有一个Controller;但是其中注入的request却是线程安全的。
优缺点:(1)注入不局限于Controller中:在方法1中,只能在Controller中加入request参数。而对于方法2,不仅可以在 Controller中注入,还可以在任何Bean中注入,包括Service、Repository及普通的Bean。
(2)注入的对象不限于request:除了注入request对象,该方法还可以注入其他scope为request或session的对象,如response对象、session对象等;并保证线程安全。
(3)减少代码冗余:只需要在需要request对象的Bean中注入request对象,便可以在该Bean的各个方法中使用,与方法1相比大大减少了代码冗余。
但是,该方法也会存在代码冗余。考虑这样的场景:web系统中有很多controller,每个controller中都会使用request对象(这种场景实际上非常频繁),这时就需要写很多次注入request的代码;如果还需要注入response,代码就更繁琐了。下面说明自动注入方法的改进方法,并分析其线程安全性及优缺点。
3、基类中自动注入,与方法2相比,将注入部分代码放入到了基类中。
优缺点:与方法2相比,避免了在不同的Controller中重复注入request;但是考虑到java只允许继承一个基类,所以如果Controller需要继承其他类时,该方法便不再好用。
无论是方法2和方法3,都只能在Bean中注入request;如果其他方法(如工具类中static方法)需要使用request对象,则需要在调用这些方法时将request参数传递进去。下面介绍的方法4,则可以直接在诸如工具类中的static方法中使用request对象(当然在各种Bean中也可以使用)。
4、手动调用
优缺点:优点:可以在非Bean中直接获取。缺点:如果使用的地方较多,代码非常繁琐;因此可以与其他方法配合使用
5、@ModelAttribute方法
分析:@ModelAttribute注解用在Controller中修饰方法时,其作用是Controller中的每个@RequestMapping方法执行前,该方法都会执行。因此在本例中,bindRequest()的作用是Controller中方法执行前为request对象赋值。虽然bindRequest()中的参数request本身是线程安全的,但由于Controller是单例的,request作为Controller的一个域,无法保证线程安全。
三、总结
综上所述,Controller中加参数(方法1)、自动注入(方法2和方法3)、手动调用(方法4)都是线程安全的,都可以用来获取request对象。如果系统中request对象使用较少,则使用哪种方式均可;如果使用较多,建议使用自动注入(方法2 和方法3)来减少代码冗余。如果需要在非Bean中使用request对象,既可以在上层调用时通过参数传入,也可以直接在方法中通过手动调用(方法4)获得。
Spring MVC中获取Request的方法及分析相关推荐
- spring MVC中获取request和response
spring MVC中获取request和response: Java代码 HttpServletRequest request = ((ServletRequestAttributes) Req ...
- Spring MVC中获取当前项目的路径
Spring MVC中获取当前项目的路径 在web.xml中加入以下内容 <!--获取项目路径--><context-param><param-name>webAp ...
- Spring中获取request的方法及其线程安全性分析
在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对象,比如获取客户端ip地址.请求的url.header中的属性(如cookie.授权信息).body中的数据等.由于 ...
- Spring MVC中处理Request和Response的策略
前沿技术早知道,弯道超车有希望 积累超车资本,从关注DD开始 作者:码农小胖哥, 图文编辑:xj 来源:https://mp.weixin.qq.com/s/3eFygsiVl8dC2nRy8_8n5 ...
- java在spring mvc中的图片接收与发送处理
1.作为client发送和获取图片 1.1.发送图片 作为client时发送图片通常是通过from-data的multipart形式来发送的,这时我们就在模拟浏览器的form文件表单来提交请求,mul ...
- Spring 中获取 request 的几种方法,及其线程安全性分析
概述 在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对象,比如获取客户端ip地址.请求的url.header中的属性(如cookie.授权信息).body中的数据等 ...
- SpringMvc4中获取request、response对象的方法
springMVC4中获取request和response对象有以下两种简单易用的方法: 1.在control层获取 在control层中获取HttpServletRequest和HttpServle ...
- Spring 2.5:Spring MVC中的新特性
转载说明:infoQ就是牛人多,看人家去年就把Spring2.5注视驱动的MVC写出来了,还是这么详细,我真是自叹不如,今天偶尔看到这篇文章非常认真的拜读了2遍,简直是茅厕顿开啊....\(^o^)/ ...
- spring mvc 异步_DeferredResult – Spring MVC中的异步处理
spring mvc 异步 DeferredResult是一个可能尚未完成的计算的容器,它将在将来提供. Spring MVC使用它来表示异步计算,并利用Servlet 3.0 AsyncContex ...
最新文章
- This Gradle plugin requires a newer IDE able to request IDE model level 3.For Android Studio this
- 声音分析+android,声音分析仪Sound Analyzer-声音分析仪 Sound Analyzer2.1安卓版-蜻蜓手游网...
- c++获得总和S所需的最小硬币数量的函数(附完整源码)
- Go Timer使用方法
- Linux系统下,虚拟终端开启256色_虚拟终端类型xterm开启256色
- mac html编辑器 免费,Mac下 10 款最棒的编辑器
- 富士康将把部分iPad和MacBook生产线从中国转移到越南
- Paravirtualization (半虚拟化PV) - Xen
- “意念打字”终成真!准确率超 99%,还登上了《Nature》封面!
- web基础、tomcat搭建
- 获取软件的apk包名、查看手机设备名称等
- pycharm如何添加桌面图标_桌面图标全变成pycharm了怎么办?
- jmete-jp@gc - Throughput Shaping Timer的使用
- 英国一名28岁女子晋升曾祖母
- 如何提升程序员的非技术才能
- 微信小程序使用mock.js
- 为什么“总结经验”反而把你带进沟里?
- TMS320C6748开发视频教程笔记 第6章 GEL 文件
- 华为三星非洲智能手机大战 低价为王
- 仙剑奇侠传三Unity开源实现
热门文章
- 后端小白程序员的Vue学习笔记
- matlab如何输出总位移,加速度转换成位移的matlab代码及说明
- C语言输出所有的水仙花数
- html的访问路径,对路径的访问被拒绝
- PCA降维算法总结以及matlab实现PCA(个人的一点理解)
- [附源码]SSM计算机毕业设计个人网站JAVA
- 武汉大专计算机专业分数线,武汉专科大学有哪些?武汉专科大学排名及分数线...
- 华为通用软件开发实习生面试题
- Virtual host / experienced an error on node rabbit@wohu-rabbit and may be inaccessible
- 项目之显示问题和回答问题(12)