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()// 所有支持的语言- 获取请求参数(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()// 获取 ServletContext7.属性操作(Attributes)
// 设置请求属性(在请求范围内共享数据)voidsetAttribute(Stringname,Objectobject)// 获取请求属性ObjectgetAttribute(Stringname)// 移除请求属性voidremoveAttribute(Stringname)// 获取所有属性名称Enumeration<String>getAttributeNames()8.其他重要方法
// 获取认证信息StringgetAuthType()booleanisSecure()// 是否使用 HTTPSPrincipalgetUserPrincipal()booleanisUserInRole(Stringrole)// 获取 Cookie 信息Cookie[]getCookies()// 获取请求调度器RequestDispatchergetRequestDispatcher(Stringpath)// 获取字符编码voidsetCharacterEncoding(Stringenv)