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() // 所有支持的语言
- 获取请求参数(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)