引言:一切请求的起点
在 Java Web 开发中,无论你使用 Spring MVC、WebSocket 还是纯 Servlet,每个请求的入口都源自一个对象------ServletRequest。这是 Servlet 规范定义的根接口,它封装了客户端请求的最基本信息:参数、属性、输入流、服务器信息等。而我们在之前深入分析的 ServerHttpRequest(Spring 对 HTTP 请求的封装)实际上是对 HttpServletRequest(ServletRequest 的子接口)的进一步抽象和增强。
今天,我们就以 ServletRequest 为核心,逐行解析其方法,并联系之前讨论的 HttpMessage、ServerHttpRequest 等接口,揭示从 Servlet 规范到 Spring Web 框架的演化脉络。
一、ServletRequest:定义与设计哲学
java
package jakarta.servlet;
public interface ServletRequest {
// ... 方法
}
- 包名 :
jakarta.servlet(从 Java EE 迁移到 Jakarta EE,但本质不变)。 - 设计目的 :提供一个与协议无关的请求信息视图。它不限定于 HTTP,可以用于任何协议(如 FTP、SMTP),但实践中几乎总是通过
HttpServletRequest子接口用于 HTTP。 - 实现者 :由 Servlet 容器(如 Tomcat、Jetty)提供具体实现,开发者通过
service(ServletRequest req, ServletResponse res)方法获得实例。
与 Spring 接口的关系:
ServletRequest是 Servlet 规范的"地基"。HttpServletRequest扩展它,增加 HTTP 协议特定方法(如getHeader、getMethod、getRequestURI)。- Spring 的
ServerHttpRequest又进一步封装HttpServletRequest,提供更便利的 API(如getHeaders()返回HttpHeaders对象)和异步控制。
二、核心方法分类解析
2.1 属性管理:请求范围内的数据容器
ServletRequest 提供了类似 Map 的属性存储,生命周期与请求一致。
java
Object getAttribute(String name);
Enumeration<String> getAttributeNames();
void setAttribute(String name, Object o);
void removeAttribute(String name);
- 作用:在请求处理链中传递数据(例如,在过滤器中设置属性,在 Servlet 中读取)。也用于容器注入特定信息(如 HTTPS 客户端证书)。
- 与
HttpRequest.getAttributes()对应 :Spring 的HttpRequest也提供了getAttributes(),但 Spring 的 attributes 是Map<String, Object>,而 Servlet 的 attributes 是Enumeration风格的旧式 API。Spring 对此进行了现代化封装。
2.2 字符编码与内容长度
java
String getCharacterEncoding();
void setCharacterEncoding(String encoding) throws UnsupportedEncodingException;
default void setCharacterEncoding(Charset encoding);
int getContentLength();
long getContentLengthLong();
String getContentType();
- 作用 :
getCharacterEncoding:获取请求体的字符编码(如 UTF-8)。若未设置,返回 null。setCharacterEncoding:必须在读取请求体(getReader()或getInputStream())之前调用,才能生效。用于覆盖默认编码。getContentLength/getContentLengthLong:获取 Content-Length 头值,-1 表示未知。getContentType:获取 Content-Type 头值(如application/json)。
- 在 Spring 中 :
HttpHeaders提供了getContentType()、getContentLength()等方法,更直接、类型安全。
2.3 输入流:读取请求体
java
ServletInputStream getInputStream() throws IOException;
BufferedReader getReader() throws IOException;
getInputStream:以二进制流方式读取请求体(用于文件上传、图片等)。getReader:以字符流方式读取请求体(用于文本数据,如 JSON、表单)。它会根据getCharacterEncoding()指定的编码自动解码。- 重要限制 :两者只能调用其一,否则抛出
IllegalStateException。 - 在 Spring 中 :
HttpInputMessage.getBody()返回InputStream,而ServerHttpRequest同时继承HttpInputMessage,因此也能通过getBody()获取原始字节流。
2.4 参数解析:查询字符串与表单数据
java
String getParameter(String name);
Enumeration<String> getParameterNames();
String[] getParameterValues(String name);
Map<String,String[]> getParameterMap();
- 作用:获取 HTTP 请求参数(Query String 或 POST 表单数据)。
- 注意 :
- 对于
application/x-www-form-urlencoded和multipart/form-data,容器会自动解析。 getParameter只返回第一个值,getParameterValues返回所有值。- 调用这些方法会触发参数解析,可能消耗输入流,因此调用
getInputStream或getReader后调用这些方法可能无效或抛出异常。
- 对于
- Spring 的等价物 :Spring MVC 通过
@RequestParam注解直接绑定参数,底层也是调用这些方法。
2.5 服务器信息:协议、主机、端口、远程地址
java
String getProtocol(); // "HTTP/1.1"
String getScheme(); // "http" 或 "https"
String getServerName(); // "example.com"
int getServerPort(); // 80
String getRemoteAddr(); // 客户端 IP
String getRemoteHost(); // 客户端主机名
int getRemotePort(); // 客户端端口
String getLocalName(); // 本地主机名
String getLocalAddr(); // 本地 IP
int getLocalPort(); // 本地端口
- 作用:获取请求到达的服务器端信息以及客户端的网络地址。
- 联系之前 :这些信息在 Spring 的
ServerHttpRequest中通过getLocalAddress()和getRemoteAddress()返回InetSocketAddress对象,比 Servlet 的分散方法更聚合。
2.6 国际化:Locale
java
Locale getLocale();
Enumeration<Locale> getLocales();
- 基于
Accept-Language头返回客户端的首选语言区域,用于国际化响应内容。
2.7 安全与分发
java
boolean isSecure(); // 是否使用 HTTPS
RequestDispatcher getRequestDispatcher(String path);
ServletContext getServletContext();
isSecure:判断请求是否通过安全通道(如 HTTPS)。getRequestDispatcher:获取一个RequestDispatcher,用于转发(forward)或包含(include)其他资源(如 JSP)。getServletContext:获取 Web 应用的上下文对象,可访问全局配置和资源。
2.8 异步处理支持(Servlet 3.0+)
java
AsyncContext startAsync() throws IllegalStateException;
AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
throws IllegalStateException;
boolean isAsyncStarted();
boolean isAsyncSupported();
AsyncContext getAsyncContext();
DispatcherType getDispatcherType();
- 作用 :开启异步模式,释放当前线程,由另一个线程处理耗时操作,完成后通过
AsyncContext完成响应。 - 与
ServerHttpAsyncRequestControl的关系 :Spring 的ServerHttpAsyncRequestControl是对这些底层方法的封装,提供更友好的start()、complete()方法。
2.9 新特性(Servlet 6.0)
java
String getRequestId();
String getProtocolRequestId();
ServletConnection getServletConnection();
getRequestId:容器生成的唯一请求标识(用于追踪)。getProtocolRequestId:协议层提供的标识(如 HTTP/2 的 stream ID)。getServletConnection:获取底层网络连接详情,提供更细粒度的网络信息。
三、ServletRequest 与 Spring 接口的对比
我们将 ServletRequest 的主要功能与 Spring 的 HttpRequest/ServerHttpRequest 对照:
| 功能 | Servlet API | Spring 抽象 |
|---|---|---|
| 获取请求头 | HttpServletRequest.getHeader() |
HttpHeaders 对象,通过 getHeaders() 获取 |
| 获取请求方法 | HttpServletRequest.getMethod() |
HttpMethod 枚举,通过 getMethod() 获取 |
| 获取 URI | HttpServletRequest.getRequestURI() |
URI 对象,通过 getURI() 获取 |
| 获取参数 | getParameter() 等 |
通过 @RequestParam 或手动解析 |
| 获取输入流 | getInputStream() / getReader() |
getBody() 返回 InputStream |
| 异步控制 | startAsync() / AsyncContext |
ServerHttpAsyncRequestControl |
| 客户端地址 | getRemoteAddr() + getRemotePort() |
getRemoteAddress() 返回 InetSocketAddress |
Spring 的设计更加面向对象 和类型安全 ,而 Servlet API 更加面向字符串 和低层。
四、在 IM 软件中的实际角色
在你的 IM 后端,ServletRequest(确切地说是 HttpServletRequest)是整个请求处理链的源头:
- WebSocket 握手 :握手请求首先到达 Servlet 容器,被包装为
HttpServletRequest,然后 Spring 的HandshakeInterceptor通过ServerHttpRequest访问其中的头、URI、远程地址等信息。 - REST API :如用户注册、登录、获取历史记录等普通 HTTP 接口,都依赖
HttpServletRequest获取参数、请求体和认证头。 - 异步处理:若某些接口需要长时间处理(如等待消息队列),可使用异步 Servlet 释放线程,提升并发能力。
因此,尽管你在 Spring 层主要与 ServerHttpRequest 打交道,但理解 ServletRequest 能帮你更好地调试和优化底层行为。
五、总结:从基石到高楼
ServletRequest 是 Servlet 规范的基石,它定义了请求对象最基本的契约。Spring 在它之上构建了更高级的抽象,但底层最终都委托给容器提供的 ServletRequest 实现。
通过对比 ServletRequest 和 ServerHttpRequest,我们可以清晰地看到 Java Web 技术的演进路径:
- 低层:面向字符串、枚举、输入流,与容器紧密耦合。
- 高层:面向对象、类型安全、更符合现代编程习惯。
在你的 IM 开发中,大部分时间你都将工作在 Spring 的高层抽象上,但当遇到性能瓶颈、需要直接操作底层容器时,对 ServletRequest 的理解会成为你的得力工具。
附录:ServletRequest 完整代码及逐行注释(节选)
java
/**
* 定义了一个向 Servlet 提供客户端请求信息的对象。
* Servlet 容器创建该对象并将其作为参数传递给 Servlet 的 service 方法。
* <p>
* 该对象提供参数名和值、属性、输入流等数据。
* 扩展该接口的接口可以提供协议特定的数据(如 {@link HttpServletRequest} 提供 HTTP 数据)。
*/
public interface ServletRequest {
/**
* 返回指定名称的属性值,若不存在则返回 null。
* 属性可由容器设置(如 HTTPS 客户端证书),也可由程序通过 setAttribute 设置。
* 属性名应以包名规范命名,以 jakarta.* 开头的保留给平台使用。
*/
Object getAttribute(String name);
/**
* 返回所有属性名的枚举。
*/
Enumeration<String> getAttributeNames();
/**
* 获取请求体使用的字符编码,若未指定则返回 null。
* 优先级:每请求设置 > Web应用默认 > 容器默认。
*/
String getCharacterEncoding();
/**
* 覆盖请求体字符编码,必须在读取请求体之前调用。
*/
void setCharacterEncoding(String encoding) throws UnsupportedEncodingException;
/**
* 获取请求体长度(字节),-1 表示未知或大于 Integer.MAX_VALUE。
*/
int getContentLength();
/**
* 获取请求体长度(长整型),-1 表示未知。
*/
long getContentLengthLong();
/**
* 获取请求体的 MIME 类型。
*/
String getContentType();
/**
* 以二进制流方式获取请求体。
* 与 getReader() 互斥。
*/
ServletInputStream getInputStream() throws IOException;
/**
* 获取参数值(单个),若参数不存在返回 null。
* 若参数有多个值,返回第一个。
* 调用该方法可能触发参数解析,需注意与输入流的关系。
*/
String getParameter(String name);
/**
* 返回所有参数名的枚举。
*/
Enumeration<String> getParameterNames();
/**
* 返回参数的所有值数组,若不存在返回 null。
*/
String[] getParameterValues(String name);
/**
* 返回参数的 Map,键为 String,值为 String[]。
*/
Map<String,String[]> getParameterMap();
/**
* 获取协议名称和版本,如 "HTTP/1.1"。
*/
String getProtocol();
/**
* 获取请求使用的协议方案(如 http, https)。
*/
String getScheme();
/**
* 获取服务器主机名。
*/
String getServerName();
/**
* 获取服务器端口。
*/
int getServerPort();
/**
* 以字符流方式获取请求体,自动按编码解码。
* 与 getInputStream() 互斥。
*/
BufferedReader getReader() throws IOException;
/**
* 获取客户端 IP 地址。
*/
String getRemoteAddr();
/**
* 获取客户端完全限定域名,若无法解析则返回 IP 地址。
*/
String getRemoteHost();
/**
* 设置请求属性。
*/
void setAttribute(String name, Object o);
/**
* 移除请求属性。
*/
void removeAttribute(String name);
/**
* 获取客户端首选语言区域。
*/
Locale getLocale();
/**
* 获取客户端可接受的语言区域列表(按优先级降序)。
*/
Enumeration<Locale> getLocales();
/**
* 判断请求是否通过安全通道(如 HTTPS)。
*/
boolean isSecure();
/**
* 获取 RequestDispatcher,用于转发或包含资源。
*/
RequestDispatcher getRequestDispatcher(String path);
/**
* 获取客户端端口。
*/
int getRemotePort();
/**
* 获取接收请求的本地主机名。
*/
String getLocalName();
/**
* 获取接收请求的本地 IP 地址。
*/
String getLocalAddr();
/**
* 获取接收请求的本地端口。
*/
int getLocalPort();
/**
* 获取 ServletContext。
*/
ServletContext getServletContext();
/**
* 启动异步处理(使用当前请求和响应)。
*/
AsyncContext startAsync() throws IllegalStateException;
/**
* 启动异步处理(指定请求和响应)。
*/
AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
throws IllegalStateException;
/**
* 判断是否已启动异步模式。
*/
boolean isAsyncStarted();
/**
* 判断是否支持异步处理。
*/
boolean isAsyncSupported();
/**
* 获取当前的 AsyncContext。
*/
AsyncContext getAsyncContext();
/**
* 获取当前请求的分发类型(如 FORWARD, INCLUDE, REQUEST, ASYNC)。
*/
DispatcherType getDispatcherType();
/**
* 获取容器生成的唯一请求标识。
*/
String getRequestId();
/**
* 获取协议层提供的请求标识(如 HTTP/2 stream ID)。
*/
String getProtocolRequestId();
/**
* 获取网络连接详情。
*/
ServletConnection getServletConnection();
}
这份源码注释不仅解释了每个方法的字面含义,还联系了 Spring 的高层抽象和你在 IM 开发中的实际场景,希望能帮助你建立从底层规范到应用框架的完整认知。
从协议无关到 HTTP 专用:HttpServletRequest 在 Web 请求处理中的核心地位
在之前的讨论中,我们已经走过了从 SocketAddress(物理地址)、URI(逻辑资源)、HttpMessage(消息头)到 ServletRequest(协议无关请求)的完整路径。今天,我们聚焦于 HttpServletRequest------它是 Servlet 规范中专门针对 HTTP 协议的请求接口,是几乎所有 Java Web 应用(包括IM 软件)与容器交互的直接入口。
HttpServletRequest 不仅继承了 ServletRequest 的所有基础能力(参数、属性、输入流),更增加了 HTTP 协议特有的功能:头处理、Cookie、会话管理、认证授权、文件上传、协议升级 等。而 Spring 的 ServerHttpRequest 则是在此基础上的进一步抽象,提供更现代、类型安全的 API。理解这三者的关系,就等于打通了从容器底层 到框架高层的任督二脉。
一、HttpServletRequest:HTTP 协议的"专属代言人"
1.1 继承与定位
java
public interface HttpServletRequest extends ServletRequest {
// ... 大量 HTTP 特定方法
}
- 继承自
ServletRequest:因此拥有所有基础方法(getAttribute、getParameter、getInputStream等)。 - 专为 HTTP 设计:所有方法都围绕 HTTP 协议的方方面面------请求行、请求头、请求体、会话、认证等。
- 由容器实现 :Tomcat、Jetty 等容器在接收到 HTTP 请求时,会创建该接口的实例,并传递给 Servlet 的
service方法(或 Spring 的DispatcherServlet)。
1.2 认证与安全相关方法
java
String getAuthType(); // 返回认证类型:BASIC, FORM, CLIENT_CERT, DIGEST
String getRemoteUser(); // 返回已认证的用户名
boolean isUserInRole(String role); // 判断用户是否属于某个角色
java.security.Principal getUserPrincipal(); // 返回 Principal 对象
boolean authenticate(HttpServletResponse response) throws IOException, ServletException;
void login(String username, String password) throws ServletException;
void logout() throws ServletException;
getUserPrincipal():这正是我们之前讨论过的java.security.Principal!它代表当前认证用户。在 Spring Security 中,它会被包装成Authentication对象。login/logout:允许在代码中手动执行登录/登出(Servlet 3.0 新增),通常与表单认证配合使用。authenticate:触发容器配置的认证机制(如 BASIC 弹窗),若未认证则返回 401。
在 IM 中的角色 :虽然你的项目使用 JWT 无状态认证,但如果你需要支持传统的 Session-based 登录,这些方法就派上用场了。而 getUserPrincipal() 可以作为获取当前用户的统一方式,与 Spring Security 集成后,principal 参数就是从这里来的。
1.3 请求头相关方法
java
String getHeader(String name);
Enumeration<String> getHeaders(String name);
Enumeration<String> getHeaderNames();
long getDateHeader(String name);
int getIntHeader(String name);
getHeader:获取第一个值(最常用)。getHeaders:获取所有值(因为有些头可以出现多次)。getDateHeader:自动解析日期格式头(如If-Modified-Since)为毫秒数。getIntHeader:解析整数值头(如Content-Length)。
与 Spring HttpHeaders 的联系 :Spring 的 HttpHeaders 类提供了更友好的类型安全方法(getFirst、getContentType() 等),并且封装了这些底层调用。
1.4 URL 与路径信息
java
String getMethod(); // GET, POST, etc.
String getRequestURI(); // /context/servlet/path
StringBuffer getRequestURL(); // http://host:port/context/servlet/path
String getContextPath(); // /myapp
String getServletPath(); // /servlet
String getPathInfo(); // 额外路径信息(如 /extra)
String getPathTranslated(); // 路径对应的真实文件系统路径
String getQueryString(); // a=b&c=d
getMethod:最常用的方法之一,用于判断请求类型。在 WebSocket 握手中,我们正是通过它检查是否为GET。- 路径分解:容器会将 URL 分解为 contextPath、servletPath、pathInfo,以便精确路由。
getRequestURL:用于构造重定向 URL 或生成绝对链接。
与 Spring ServerHttpRequest 的关系 :Spring 通过 getURI() 返回一个 java.net.URI 对象,包含了所有这些信息,但以更现代的方式呈现。
1.5 Cookie 与会话管理
java
Cookie[] getCookies();
String getRequestedSessionId();
boolean isRequestedSessionIdValid();
boolean isRequestedSessionIdFromCookie();
boolean isRequestedSessionIdFromURL();
HttpSession getSession(boolean create);
HttpSession getSession();
String changeSessionId();
- Cookie:获取客户端发送的 Cookie 数组。
- 会话管理 :
getSession()用于获取或创建HttpSession,它是服务器端保存用户状态的主要机制(在无状态 JWT 时代使用较少,但在传统 Web 应用中仍广泛使用)。 - 会话 ID 追踪:检查会话 ID 来源(Cookie 或 URL),判断是否有效。
在 IM 中的角色 :虽然你的 IM 可能主要使用 JWT,但 Spring Security 的默认会话管理仍基于 HttpSession,理解这些方法有助于调试。
1.6 文件上传与 Multipart 支持(Servlet 3.0+)
java
Collection<Part> getParts() throws IOException, ServletException;
Part getPart(String name) throws IOException, ServletException;
getParts():获取所有上传的文件部分(Part对象)。getPart(name):按名称获取特定部分。- 前提:请求的
Content-Type为multipart/form-data,且 Servlet 配置了@MultipartConfig。
在 IM 中的潜在应用:头像上传、文件传输等场景会用到。
1.7 协议升级与 HTTP/2 支持
java
<T extends HttpUpgradeHandler> T upgrade(Class<T> httpUpgradeHandlerClass) throws IOException, ServletException;
default PushBuilder newPushBuilder() { return null; } // @Deprecated
default Map<String,String> getTrailerFields() { return Collections.emptyMap(); }
default boolean isTrailerFieldsReady() { return true; }
default HttpServletMapping getHttpServletMapping() { ... }
upgrade(Servlet 3.1+):这是 WebSocket 握手的关键方法 !当容器检测到Upgrade: websocket头时,可以调用此方法将当前 HTTP 连接升级为 WebSocket 协议,并传入自定义的HttpUpgradeHandler实现。getTrailerFields(HTTP/2):获取尾部字段(Trailer),用于分块传输编码后的附加头。newPushBuilder(Servlet 4.0,已弃用):用于 HTTP/2 服务器推送,现推荐使用 103 Early Hints。
在 IM 中的核心角色 :对于 WebSocket,upgrade 方法是容器级支持的基础。不过,Spring WebSocket 封装了底层细节,你通常不需要直接调用它。
二、与 ServletRequest 的区别和联系
| 维度 | ServletRequest |
HttpServletRequest |
|---|---|---|
| 协议范围 | 与协议无关(可代表 FTP、SMTP 等) | 专门针对 HTTP/HTTPS |
| 核心方法 | 参数、属性、输入流、服务器信息 | 增加:头、Cookie、会话、认证、路径分解、上传、升级 |
| 主要用途 | 作为所有请求的根接口 | 作为 Web 应用的 HTTP 请求标准接口 |
| 实现者 | 容器提供(如 Request 基类) |
容器提供(如 Request 的 HTTP 子类) |
联系 :HttpServletRequest 继承 自 ServletRequest,因此它拥有父接口的所有方法,并在此基础上扩展。你的代码中若只依赖 ServletRequest,则可适用于任何协议;若使用 HttpServletRequest,则仅限于 HTTP。
三、与 ServerHttpRequest 的区别和联系
ServerHttpRequest 是 Spring 框架中定义的服务端 HTTP 请求抽象,它并不直接继承 HttpServletRequest,而是封装它。
| 维度 | HttpServletRequest(Servlet API) |
ServerHttpRequest(Spring) |
|---|---|---|
| 所属规范 | Jakarta Servlet(Java EE / Jakarta EE) | Spring Framework |
| 底层实现 | 由容器(Tomcat/Jetty)直接实现 | 通常是 Spring 的包装类,内部持有 HttpServletRequest |
| 主要方法 | 众多基于字符串和枚举的方法(如 getHeader(String)) |
更面向对象:getHeaders() 返回 HttpHeaders,getMethod() 返回 HttpMethod 枚举,getURI() 返回 URI |
| 异步支持 | startAsync() 返回 AsyncContext |
getAsyncRequestControl() 返回 ServerHttpAsyncRequestControl(更易用) |
| 网络地址 | getRemoteAddr()、getRemotePort() 分开 |
getRemoteAddress() 返回统一的 InetSocketAddress |
| 用户身份 | getUserPrincipal() 返回 Principal |
同样有 getPrincipal() 方法,但通常 Spring Security 会包装 |
联系:
- Spring 的
ServerHttpRequest通常通过适配器模式封装HttpServletRequest。 - 在
HandshakeInterceptor中,你收到的是ServerHttpRequest,但内部可以通过getNativeRequest()获取底层的HttpServletRequest对象(若需调用 Servlet 特有方法)。 - Spring 提供更现代、类型安全的 API,避免直接操作字符串和枚举。
四、HttpServletRequest 在你的 IM 中的实际应用
尽管你主要工作在 Spring 层,但理解 HttpServletRequest 有助于:
- 调试:当遇到容器相关问题时,查看原始请求头和方法。
- 性能调优 :例如,通过
getContentLengthLong()了解请求体大小,提前拒绝过大请求。 - WebSocket 握手 :虽然 Spring 隐藏了
upgrade,但原理上握手正是通过调用upgrade方法完成的。 - 混合架构 :若你还需要提供 REST API,使用
HttpServletRequest获取原始参数和请求体。 - 安全 :
getRemoteAddr()和getRemoteHost()用于 IP 黑白名单,isSecure()用于强制 HTTPS。
五、总结:从 ServletRequest 到 ServerHttpRequest 的进化
ServletRequest:基础,提供与协议无关的请求模型。HttpServletRequest:专用化,增加 HTTP 协议特性,是 Servlet 规范的核心。ServerHttpRequest:现代化封装,提供更友好、类型安全的 API,同时保留对底层的访问能力。
在你的 IM 开发中,三者形成了清晰的层次:
- 底层 :容器提供
HttpServletRequest。 - 中间层 :Spring 将其包装为
ServerHttpRequest,并注入HandshakeInterceptor。 - 上层 :你的业务代码通过
Principal、HttpHeaders等高级抽象操作请求。
理解这层关系,你就能在需要时灵活地在不同层次间切换,写出更健壮、更高效的代码。
附录:HttpServletRequest 核心方法详解(按功能分组)
认证与用户身份
getAuthType()→ 返回认证机制。getRemoteUser()→ 返回已认证用户名。isUserInRole(String)→ 角色检查。getUserPrincipal()→ 返回Principal对象。login(String, String)/logout()→ 程序化登录/登出。authenticate(HttpServletResponse)→ 触发容器认证。
请求头
getHeader(String)→ 获取首值。getHeaders(String)→ 获取所有值。getHeaderNames()→ 获取所有头名。getDateHeader(String)→ 解析日期头。getIntHeader(String)→ 解析整型头。
请求方法与 URL
getMethod()→ HTTP 方法。getRequestURI()→ 原始路径(不含主机和查询)。getRequestURL()→ 完整 URL(不含查询)。getContextPath()→ 应用上下文路径。getServletPath()→ Servlet 匹配路径。getPathInfo()→ 额外路径信息。getPathTranslated()→ 真实文件路径。getQueryString()→ 查询字符串。
会话
getSession(boolean)→ 获取/创建会话。getSession()→ 默认创建。getRequestedSessionId()→ 客户端提供的会话 ID。isRequestedSessionIdValid()→ 是否有效。isRequestedSessionIdFromCookie()/fromURL()→ 来源。changeSessionId()→ 更换会话 ID。
文件上传
getParts()→ 获取所有上传部件。getPart(String)→ 获取指定部件。
协议升级与高级特性
upgrade(Class)→ 升级到 WebSocket 等。newPushBuilder()→ HTTP/2 推送(已弃用)。getTrailerFields()→ 尾部字段。isTrailerFieldsReady()→ 尾部是否就绪。getHttpServletMapping()→ 获取映射信息。
通过这篇分析,你将 HttpServletRequest 放在整个 Servlet 和 Spring 生态的上下文之中,能更清晰地理解每个方法的设计初衷和实际用途。