RequestAttributes , ServletRequestAttributes学习

java 复制代码
 public static ServletRequestAttributes getRequestAttributes()
    {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }

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

java 复制代码
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();

作用:从 Spring 的上下文(基于 ThreadLocal)中获取当前线程绑定的请求属性对象。

返回类型:RequestAttributes(这是一个 接口)

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

原理

Spring 在处理每个 HTTP 请求时(通过 DispatcherServlet)会:

创建 ServletRequestAttributes 对象,包装 HttpServletRequest 和 HttpServletResponse

调用 RequestContextHolder.setRequestAttributes(...) 将其存入 ThreadLocal

请求结束后自动清理

因此,在同一个请求线程中,任何地方调用 getRequestAttributes() 都能拿到这个对象。

「接口-实现类」关系

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

java 复制代码
// 定义接口
interface Animal {
    void makeSound();
}

// 实现类
class Dog implements Animal {
    public void makeSound() {
        System.out.println("汪汪!");
    }
}

// 使用
Animal myPet = new Dog(); // ✅ 合法!把 Dog 对象赋值给 Animal 接口变量
myPet.makeSound();        // 输出:汪汪!

问题来了,为什么要强制转换一下呢

Animal 这个例子里面 是因为 接口定义了makeSound 方法, 所以可以直接使用

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

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

ServletRequestAttributes

java 复制代码
public class ServletRequestAttributes implements RequestAttributes, Serializable

// 获取 HttpServletRequest

public HttpServletRequest getRequest()

// 获取 HttpServletResponse

public HttpServletResponse getResponse()

// 获取 HttpSession(可选择是否创建)

public HttpSession getSession(boolean create)

// 获取原生的 ServletContext

public ServletContext getServletContext()

java 复制代码
// 1. 获取当前请求上下文
ServletRequestAttributes attributes = 
    (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

// 2. 获取原始请求/响应对象
HttpServletRequest request = attributes.getRequest();
HttpServletResponse response = attributes.getResponse();

// 3. 操作请求属性
attributes.setAttribute("userId", "123", RequestAttributes.SCOPE_REQUEST);
String userId = (String) attributes.getAttribute("userId", RequestAttributes.SCOPE_REQUEST);

// 4. 操作会话属性
attributes.setAttribute("cart", shoppingCart, RequestAttributes.SCOPE_SESSION);
Object cart = attributes.getAttribute("cart", RequestAttributes.SCOPE_SESSION);

// 5. 获取会话
HttpSession session = attributes.getSession(true);```

HttpServletRequest request 的方法

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

java 复制代码
// 获取 HTTP 方法(GET、POST、PUT、DELETE 等)
String getMethod()

// 获取请求的 URI(不包含协议、主机、端口)
String getRequestURI()

// 获取完整的请求 URL(包含协议、主机、端口、URI)
StringBuffer getRequestURL()

// 获取查询字符串(URL 中 ? 后面的部分)
String getQueryString()

// 获取协议及版本(如 HTTP/1.1)
String getProtocol()

// 获取上下文路径(应用的部署路径,以 / 开头)
String getContextPath()

// 获取 Servlet 路径(映射到当前 Servlet 的路径)
String getServletPath()

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

java 复制代码
// 获取指定请求头的值(单个值)
String getHeader(String name)

// 获取指定请求头的所有值(多个值的情况)
Enumeration<String> getHeaders(String name)

// 获取所有请求头的名称
Enumeration<String> getHeaderNames()

// 常用的特定请求头方法:
String getContentType()        // Content-Type
int getContentLength()         // Content-Length
long getContentLengthLong()    // Content-Length (long 类型)
String getCharacterEncoding()  // 字符编码
Locale getLocale()             // 客户端首选语言
Enumeration<Locale> getLocales() // 所有支持的语言
  1. 获取请求参数(Request Parameters)
java 复制代码
// 获取单个参数值
String getParameter(String name)

// 获取参数的所有值(用于多选框等)
String[] getParameterValues(String name)

// 获取所有参数名称
Enumeration<String> getParameterNames()

// 获取所有参数的 Map(参数名 → 参数值数组)
Map<String, String[]> getParameterMap()

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

java 复制代码
// 获取输入流(用于读取原始请求体)
ServletInputStream getInputStream()

// 获取字符阅读器(用于读取文本请求体)
BufferedReader getReader()

5.获取会话信息(Session)

java 复制代码
// 获取当前会话(如果不存在则创建)
HttpSession getSession()

// 获取当前会话(可选择是否创建)
HttpSession getSession(boolean create)

// 判断是否已有会话
boolean isRequestedSessionIdValid()
boolean isRequestedSessionIdFromCookie()
boolean isRequestedSessionIdFromURL()

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

java 复制代码
// 客户端信息
String getRemoteAddr()     // 客户端 IP 地址
String getRemoteHost()     // 客户端主机名
int getRemotePort()        // 客户端端口

// 服务器信息  
String getLocalAddr()      // 服务器 IP 地址
String getLocalName()      // 服务器主机名
int getLocalPort()         // 服务器端口
String getServerName()     // 服务器主机名
int getServerPort()        // 服务器端口

// 转发/包含信息
String getRealPath(String path) // 获取真实文件系统路径(已废弃)
ServletContext getServletContext() // 获取 ServletContext

7.属性操作(Attributes)

java 复制代码
// 设置请求属性(在请求范围内共享数据)
void setAttribute(String name, Object object)

// 获取请求属性
Object getAttribute(String name)

// 移除请求属性
void removeAttribute(String name)

// 获取所有属性名称
Enumeration<String> getAttributeNames()

8.其他重要方法

java 复制代码
// 获取认证信息
String getAuthType()
boolean isSecure()         // 是否使用 HTTPS
Principal getUserPrincipal()
boolean isUserInRole(String role)

// 获取 Cookie 信息
Cookie[] getCookies()

// 获取请求调度器
RequestDispatcher getRequestDispatcher(String path)

// 获取字符编码
void setCharacterEncoding(String env)
相关推荐
蒸蒸yyyyzwd11 小时前
秋招不熟悉力扣学习笔记1
笔记·学习·leetcode
小弥儿12 小时前
GitHub今日热榜 | 2026-08-11:图原生基础设施首日登顶
学习·开源·github
for_ever_love__15 小时前
python基础语法学习: 数据容器
windows·python·学习
云空16 小时前
《电子专业完整学习路线图(分两套:本科四年版 / 零基础自学速成版)》
科技·学习·学习方法·高考
min(a,b)16 小时前
学习第16天:LangGraph 与 Agent 工作流编排
学习
woshihuanglaoshi16 小时前
鸿蒙技术进阶全景高级成长体系:从初中级到架构师的技能树/学习路径/项目实战/认证体系系统性方法论
学习·华为·harmonyos
AI即插即用16 小时前
即插即用系列 | IEEE TMI PLG-HN:原型学习引导的 CNN-Transformer 混合网络,攻克乳腺肿瘤分割难题
人工智能·深度学习·神经网络·学习·目标检测·cnn·transformer
leo_messi9418 小时前
langchain学习(三) - tools使用
学习·langchain
for_ever_love__18 小时前
python基础语法学习: 变量, 输入输出, 运算符
网络·python·学习
学习和思考18 小时前
非自动化专业如何自学PLC?我的6个月学习路线图
笔记·学习·自动化·学习方法