当前位置: 首页 > news >正文

RequestAttributes , ServletRequestAttributes学习

publicstaticServletRequestAttributesgetRequestAttributes(){RequestAttributesattributes=RequestContextHolder.getRequestAttributes();return(ServletRequestAttributes)attributes;}

是 获取当前 HTTP 请求上下文的标准两步操作

RequestAttributesattributes=RequestContextHolder.getRequestAttributes();

作用:从 Spring 的上下文(基于 ThreadLocal)中获取当前线程绑定的请求属性对象。
返回类型:RequestAttributes(这是一个 接口)

在 Web 环境(如 Spring MVC 处理 HTTP 请求时)→ 实际是 ServletRequestAttributes 实例

原理

Spring 在处理每个 HTTP 请求时(通过 DispatcherServlet)会:
创建 ServletRequestAttributes 对象,包装 HttpServletRequest 和 HttpServletResponse
调用 RequestContextHolder.setRequestAttributes(…) 将其存入 ThreadLocal
请求结束后自动清理
因此,在同一个请求线程中,任何地方调用 getRequestAttributes() 都能拿到这个对象。

「接口-实现类」关系

RequestAttributes 和 ServletRequestAttributes 是典型的「接口-实现类」关系,也就是你所说的“父子关系”(更准确地说,是 接口与其实现类的关系)

// 定义接口interfaceAnimal{voidmakeSound();}// 实现类classDogimplementsAnimal{publicvoidmakeSound(){System.out.println("汪汪!");}}// 使用AnimalmyPet=newDog();// ✅ 合法!把 Dog 对象赋值给 Animal 接口变量myPet.makeSound();// 输出:汪汪!

问题来了,为什么要强制转换一下呢
Animal 这个例子里面 是因为 接口定义了makeSound 方法, 所以可以直接使用

但如果方法里没有实现呢? 类在实现的时候新增的方法,就需要强制转换,才可以使用

说法是否正确
“可以把对象赋值给它的接口”✅ 完全正确
“接口变量持有对象的实际类型信息”✅ 是的(运行时保留)
“通过接口变量能调用子类所有方法”❌ 只能调用接口中声明的方法
“这是 Java 多态的基础”✅ 正确

ServletRequestAttributes

publicclassServletRequestAttributesimplementsRequestAttributes,Serializable

// 获取 HttpServletRequest
public HttpServletRequest getRequest()

// 获取 HttpServletResponse
public HttpServletResponse getResponse()

// 获取 HttpSession(可选择是否创建)
public HttpSession getSession(boolean create)

// 获取原生的 ServletContext
public ServletContext getServletContext()

// 1. 获取当前请求上下文ServletRequestAttributesattributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();// 2. 获取原始请求/响应对象HttpServletRequestrequest=attributes.getRequest();HttpServletResponseresponse=attributes.getResponse();// 3. 操作请求属性attributes.setAttribute("userId","123",RequestAttributes.SCOPE_REQUEST);StringuserId=(String)attributes.getAttribute("userId",RequestAttributes.SCOPE_REQUEST);// 4. 操作会话属性attributes.setAttribute("cart",shoppingCart,RequestAttributes.SCOPE_SESSION);Objectcart=attributes.getAttribute("cart",RequestAttributes.SCOPE_SESSION);// 5. 获取会话HttpSessionsession=attributes.getSession(true);```

HttpServletRequest request 的方法

1.获取请求行信息(Request Line)

// 获取 HTTP 方法(GET、POST、PUT、DELETE 等)StringgetMethod()// 获取请求的 URI(不包含协议、主机、端口)StringgetRequestURI()// 获取完整的请求 URL(包含协议、主机、端口、URI)StringBuffergetRequestURL()// 获取查询字符串(URL 中 ? 后面的部分)StringgetQueryString()// 获取协议及版本(如 HTTP/1.1)StringgetProtocol()// 获取上下文路径(应用的部署路径,以 / 开头)StringgetContextPath()// 获取 Servlet 路径(映射到当前 Servlet 的路径)StringgetServletPath()

2.获取请求头信息(Request Headers)

// 获取指定请求头的值(单个值)StringgetHeader(Stringname)// 获取指定请求头的所有值(多个值的情况)Enumeration<String>getHeaders(Stringname)// 获取所有请求头的名称Enumeration<String>getHeaderNames()// 常用的特定请求头方法:StringgetContentType()// Content-TypeintgetContentLength()// Content-LengthlonggetContentLengthLong()// Content-Length (long 类型)StringgetCharacterEncoding()// 字符编码LocalegetLocale()// 客户端首选语言Enumeration<Locale>getLocales()// 所有支持的语言
  1. 获取请求参数(Request Parameters)
// 获取单个参数值StringgetParameter(Stringname)// 获取参数的所有值(用于多选框等)String[]getParameterValues(Stringname)// 获取所有参数名称Enumeration<String>getParameterNames()// 获取所有参数的 Map(参数名 → 参数值数组)Map<String,String[]>getParameterMap()

4.获取请求体数据(Request Body)

// 获取输入流(用于读取原始请求体)ServletInputStreamgetInputStream()// 获取字符阅读器(用于读取文本请求体)BufferedReadergetReader()

5.获取会话信息(Session)

// 获取当前会话(如果不存在则创建)HttpSessiongetSession()// 获取当前会话(可选择是否创建)HttpSessiongetSession(booleancreate)// 判断是否已有会话booleanisRequestedSessionIdValid()booleanisRequestedSessionIdFromCookie()booleanisRequestedSessionIdFromURL()

6.获取客户端和服务器信息

// 客户端信息StringgetRemoteAddr()// 客户端 IP 地址StringgetRemoteHost()// 客户端主机名intgetRemotePort()// 客户端端口// 服务器信息StringgetLocalAddr()// 服务器 IP 地址StringgetLocalName()// 服务器主机名intgetLocalPort()// 服务器端口StringgetServerName()// 服务器主机名intgetServerPort()// 服务器端口// 转发/包含信息StringgetRealPath(Stringpath)// 获取真实文件系统路径(已废弃)ServletContextgetServletContext()// 获取 ServletContext

7.属性操作(Attributes)

// 设置请求属性(在请求范围内共享数据)voidsetAttribute(Stringname,Objectobject)// 获取请求属性ObjectgetAttribute(Stringname)// 移除请求属性voidremoveAttribute(Stringname)// 获取所有属性名称Enumeration<String>getAttributeNames()

8.其他重要方法

// 获取认证信息StringgetAuthType()booleanisSecure()// 是否使用 HTTPSPrincipalgetUserPrincipal()booleanisUserInRole(Stringrole)// 获取 Cookie 信息Cookie[]getCookies()// 获取请求调度器RequestDispatchergetRequestDispatcher(Stringpath)// 获取字符编码voidsetCharacterEncoding(Stringenv)
http://www.jsqmd.com/news/657689/

相关文章:

  • Python实现图形化井字棋——人机对战
  • 从JTAG到EJTAG:揭秘龙芯处理器片上调试的硬件基石
  • 大模型RAG (一)
  • 2026 学术降维打击:9 大 AI 查重降重工具,从重复率 99% 到安全过审全攻略
  • 大模型的参数量-为什么 24B 是一个“甜蜜点“?
  • 5分钟快速上手:开源视频智能分析工具的完整指南
  • vivo X300 Ultra长焦套件集市游玩体验佳,小巧轻便成家庭出游必备!
  • 嵌入式老鸟的VSCode私房插件清单:除了C/C++,这些调试和效率工具让你事半功倍
  • BilibiliUploader:Python自动化投稿工具的高效解决方案
  • 从零搭建思澈科技SiFli-Solution开发环境:避坑指南与实战演练
  • 【SITS2026官方认证指南】:AI文档生成工具选型、落地与合规避坑的7大黄金法则
  • 为了追求极致的性能,光学系统必须从“组装件”向“整体件”转变
  • 微软新 Xbox 负责人阿莎·夏尔马忙不停:Game Pass 定价待调,“螺旋计划”影响几何?
  • day3-实训学习记录
  • 百度网盘秒传工具终极指南:3分钟掌握快速转存技巧
  • 若依WMS仓库管理系统:企业级仓储管理的现代化解决方案
  • 花0.5s用openclaw写出来的vx小游戏,运行跑完全程无误,欢迎来找茬~
  • 告别base环境自动激活:CentOS7安装Miniconda后必做的几项贴心配置
  • 从DALL·E到Stable Diffusion:VQGAN编码器为何仍是AIGC的幕后功臣?
  • 大模型智能体与MCP(三) 使用ollama本地部署Deepseek R1 32B模型
  • 一区Top/IF 8.3!六大老年数据库联合争议话题,澳门大学博士这篇文章真的赢麻了
  • 从复古游戏到电子墨水屏:聊聊Floyd-Steinberg抖动算法的那些神奇应用场景
  • 终极指南:如何用lunar-javascript构建专业级农历计算应用
  • STM32掉电保护实战:用PVD在断电瞬间保存关键数据(附HAL库代码)
  • ComfyUI ControlNet Aux:30+预处理器的AI绘画精准控制解决方案
  • 【仅限2026Q1有效】SITS2026圆桌推荐:5套可立即嵌入CI/CD的AIGC代码可信性校验工具链(含开源License兼容性清单)
  • 基于SPDConv(空间-深度卷积)-BiLSTM (双向长短期记忆神经网络)多变量时间序列预测
  • 别光刷题了!用这5个真实嵌入式项目片段,检验你的C语言功底到底扎不扎实
  • 图片批量添加满屏文字水印工具:Windows桌面端实操指南
  • 揭秘Rescuezilla:系统恢复领域的瑞士军刀深度解析