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)
相关推荐
weixin_513449962 小时前
PCA、SVD 、 ICP 、kd-tree算法的简单整理总结
c++·人工智能·学习·算法·机器人
鱼鳞_2 小时前
Java学习笔记_Day29(异常)
java·笔记·学习
嵌入式小企鹅3 小时前
DeepSeek-V4昇腾首发、国芯抗量子MCU突破、AI编程Agent抢班夺权
人工智能·学习·ai·程序员·算力·risc-v
Amazing_Cacao4 小时前
CFCA精品可可产区认证课程风土解析(亚洲):撕开标签伪装,将微气候差异转化为可用变量
学习
我的xiaodoujiao4 小时前
API 接口自动化测试详细图文教程学习系列11--Requests模块3--测试练习
开发语言·python·学习·测试工具·pytest
墨澜逸客4 小时前
《华胥文化》百回大纲
学习·其他·百度·学习方法·新浪微博
Stella Blog4 小时前
狂神Java基础学习笔记Day04
java·笔记·学习
一只机电自动化菜鸟4 小时前
一建机电备考笔记(17) 常用设备—通用设备1(含考频+题型)
笔记·学习·职场和发展·生活·学习方法
深蓝海拓4 小时前
基于QtPy (PySide6) 的PLC-HMI工程项目(十)框架初成的阶段总结
网络·笔记·python·学习·ui·plc