SpringMvc中获取Request

简介:

目录

 ●   Controller中加参数
 ●   自动注入
 ●   基类中自动注入
 ●   手动调用

 ●  @ModelAttribute方法

Controller中加参数

 
  1. @Controller

  2. public class TestController {

  3. @RequestMapping("/test")

  4. public void test(HttpServletRequest request) {

  5. ......

  6. }

  7. }

Controller中获取request对象后,如果要在其他方法中(如service方法、工具类方法等)使用request对象,需要在调用这些方法时将request对象作为参数传入

此时request对象是方法参数,相当于局部变量,毫无疑问是线程安全的。

自动注入

 
  1. @Controller

  2. public class TestController{

  3. @Autowired

  4. private HttpServletRequest request; //自动注入request

  5. @RequestMapping("/test")

  6. public void test() throws InterruptedException{

  7. ......

  8. }

  9. }

使用这种方式,当Bean(本例的TestController)初始化时,Spring并没有注入一个request对象,而是注入了一个代理(proxy);当Bean中需要使用request对象时,通过该代理获取request对象。request实际上是一个代理:代理的实现参见AutowireUtils的内部类ObjectFactoryDelegatingInvocationHandler。

调用request的方法method时,实际上是调用了由objectFactory.getObject()生成的对象的method方法;objectFactory.getObject()生成的对象才是真正的request对象。

objectFactory的类型为WebApplicationContextUtils的内部类RequestObjectFactory;而RequestObjectFactory要获得request对象需要先调用currentRequestAttributes()方法获得RequestAttributes对象,生成RequestAttributes对象的核心代码在类RequestContextHolder中,生成的RequestAttributes对象是线程局部变量(ThreadLocal),因此request对象也是线程局部变量;这就保证了request对象的线程安全性。

基类中自动注入

 
  1. public class BaseController {

  2. @Autowired

  3. protected HttpServletRequest request;

  4. }

  5. @Controller

  6. public class TestController extends BaseController {

  7. }

与方法2相比,避免了在不同的Controller中重复注入request;但是考虑到java只允许继承一个基类,所以如果Controller需要继承其他类时,该方法便不再好用。

手动调用

 
  1. @Controller

  2. public class TestController {

  3. @RequestMapping("/test")

  4. public void test() throws InterruptedException {

  5. HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();

  6. .......

  7. }

  8. }

通过自动注入实现与通过手动方法调用实现原理差不多。因此本方法也是线程安全的。

优点:可以在非Bean中直接获取。缺点:如果使用的地方较多,代码非常繁琐;因此可以与其他方法配合使用。

@ModelAttribute方法

 
  1. @Controller

  2. public class TestController {

  3. private HttpServletRequest request; 此处线程不安全

  4. @ModelAttribute

  5. public void bindRequest(HttpServletRequest request) {

  6. this.request = request; 此处request线程安全

  7. }

  8. @RequestMapping("/test")

  9. public void test() throws InterruptedException {

  10. ......

  11. }

  12. }

@ModelAttribute注解用在Controller中修饰方法时,其作用是Controller中的每个@RequestMapping方法执行前,该方法都会执行。bindRequest()的作用是在test()执行前为request对象赋值。虽然bindRequest()中的参数request本身是线程安全的,但由于TestController是单例的,request作为TestController的一个域,无法保证线程安全。


原文发布时间为:2018-11-16
本文来自云栖社区合作伙伴“ Java杂记”,了解相关信息可以关注“ Java杂记”。
相关文章
|
存储 算法 关系型数据库
【CEPH-初识篇】ceph详细介绍、搭建集群及使用,带你认识新大陆
你好,我是无名小歌。 今天给大家分享一个分布式存储系统ceph。 什么是ceph? Ceph在一个统一的系统中独特地提供对象、块和文件存储。Ceph 高度可靠、易于管理且免费。Ceph 的强大功能可以改变您公司的 IT 基础架构和管理大量数据的能力。Ceph 提供了非凡的可扩展性——数以千计的客户端访问 PB 到 EB 的数据。ceph存储集群相互通信以动态复制和重新分配数据。
1822 0
【CEPH-初识篇】ceph详细介绍、搭建集群及使用,带你认识新大陆
|
C++ Python
vsCode修改字体为JetBrains Mono (PyCharm默认字体)
vsCode修改字体为JetBrains Mono (PyCharm默认字体)
4378 0
vsCode修改字体为JetBrains Mono (PyCharm默认字体)
|
4月前
|
存储 数据采集 数据处理
大模型RAG实战:从零搭建专属知识库问答助手
本文介绍如何用RAG技术从零搭建个人Python知识库问答助手,无需代码基础,低成本实现智能问答。涵盖数据准备、向量存储、检索生成全流程,附避坑技巧与优化方法,助力新手快速上手大模型应用。
|
Linux Python
centos 编译安装 python 和 openssl
centos 编译安装 python 和 openssl
871 3
|
前端开发 开发者
useContext 钩子详解
【10月更文挑战第14天】`useContext` 是 React 中的一个 Hook,用于在组件树中传递数据,避免手动传递 props。本文从基本概念、使用方法、常见问题及解决方法等方面详细介绍了 `useContext`,并提供了代码示例,帮助开发者更好地理解和应用这一钩子。
632 6
|
前端开发 关系型数据库 MySQL
Python基于Django框架图书管理系统,Bootstrap框架UI,后台EasyUI框架UI,有登录,实现增删改查的富文本效果
本文介绍了一个使用Python Django框架开发的图书管理系统,该系统采用Bootstrap框架进行前端UI设计,EasyUI框架用于后台UI界面,集成了富文本编辑器,并实现了登录及增删改查功能。
672 1
|
存储 分布式计算 大数据
阿里云大数据ACA及ACP复习题(41~50)
本人备考阿里云大数据考试时自行收集准备的题库,纯手工整理的,能够覆盖到今年7月份,应该是目前最新的,发成文章希望大家能一起学习,不要花冤枉钱去买题库背了,也希望大家能够顺利通关ACA和ACP考试。
|
存储 JSON 5G
短视频批量制作-常用功能
越来越多的产品选择使用短视频作为内容承载,通过对媒体素材进行简单的剪辑,即可进行使用和投放,本文基于智能媒体服务IMS,介绍短视频剪辑中的常用功能,通过对不同功能的组合,方便客户组装自己的剪辑场景,进行短视频批量合成。
937 0
短视频批量制作-常用功能