Java Web 请求处理:HttpServletRequest 详解
在 Java Web 开发中,客户端的 HTTP 请求由 HttpServletRequest 对象封装,它提供了丰富的方法用于获取请求行、请求头、请求参数等信息。本文将系统梳理 HttpServletRequest 的核心功能,包括请求行解析、请求头获取、参数处理及会话管理等,帮助开发者高效处理客户端请求。
HttpServletRequest 概述
HttpServletRequest 是 ServletRequest 接口的子接口,专门用于处理 HTTP 协议的请求。它由 Servlet 容器创建并传递给 service() 方法,包含客户端请求的所有信息(如 URL、参数、 headers 等)。
1 | // HttpServlet 中处理请求的方法 |
请求行信息获取
HTTP 请求行由请求方法(如 GET/POST)、请求 URI 和协议版本组成(如 GET /index.jsp HTTP/1.1)。HttpServletRequest 提供以下方法解析请求行:
| 方法 | 作用描述 | 示例(假设请求为 GET /app/user?id=1 HTTP/1.1) |
|---|---|---|
getMethod() |
获取请求方法(GET/POST/PUT/DELETE 等) | GET |
getProtocol() |
获取协议版本(如 HTTP/1.1) |
HTTP/1.1 |
getRequestURI() |
获取请求 URI(主机名后的路径部分) | /app/user |
getRequestURL() |
获取完整请求 URL(包含协议、主机、端口和路径) | http://localhost:8080/app/user |
getQueryString() |
获取 URL 中的查询参数(? 后的部分) |
id=1 |
getContextPath() |
获取当前 Web 应用的上下文路径(部署路径) | /app |
getServletPath() |
获取 Servlet 映射的路径 | /user |
getPathInfo() |
获取 URL 中 Servlet 路径后的额外路径信息(无则为 null) |
null(若请求为 /app/user/1,则返回 /1) |
网络连接信息
获取客户端与服务器的网络连接细节,如 IP、端口等:
| 方法 | 作用描述 |
|---|---|
getRemoteAddr() |
获取客户端 IP 地址 |
getRemoteHost() |
获取客户端主机名(可能与 IP 相同,取决于 DNS 配置) |
getRemotePort() |
获取客户端端口号 |
getLocalAddr() |
获取服务器接收请求的 IP 地址 |
getLocalPort() |
获取服务器接收请求的端口号 |
getServerName() |
获取请求指向的服务器主机名(如 localhost) |
getServerPort() |
获取服务器监听的端口号(如 8080) |
getScheme() |
获取协议名(如 http 或 https) |
请求头信息处理
HTTP 请求头包含客户端的附加信息(如浏览器类型、数据类型等),HttpServletRequest 提供以下方法获取:
| 方法 | 作用描述 |
|---|---|
getHeader(String name) |
获取指定名称的请求头值(如 User-Agent) |
getHeaders(String name) |
获取指定名称的所有请求头值(返回 Enumeration<String>) |
getHeaderNames() |
获取所有请求头的名称(返回 Enumeration<String>) |
getIntHeader(String name) |
获取整数类型的请求头(如 Content-Length) |
getDateHeader(String name) |
获取日期类型的请求头(返回毫秒时间戳,如 If-Modified-Since) |
getContentLength() |
获取 Content-Length 头的值(请求体长度,单位字节) |
getContentType() |
获取 Content-Type 头的值(如 application/x-www-form-urlencoded) |
getCharacterEncoding() |
获取请求体的字符编码(从 Content-Type 头提取,如 UTF-8) |
示例:获取浏览器类型
1 | String userAgent = request.getHeader("User-Agent"); |
请求参数处理
请求参数是客户端传递给服务器的数据,可通过 URL query 或请求体发送。HttpServletRequest 提供多种方法解析参数:
基本参数获取
| 方法 | 作用描述 |
|---|---|
getParameter(String name) |
获取指定名称的参数值(适用于单值参数) |
getParameterValues(String name) |
获取指定名称的所有参数值(适用于多值参数,如复选框) |
getParameterNames() |
获取所有参数名称(返回 Enumeration<String>) |
getParameterMap() |
获取所有参数的键值对(返回 Map<String, String[]>) |
示例:处理表单提交的参数
1 | // 假设请求参数为:username=zhangsan&hobby=reading&hobby=sports |
原始请求体读取
对于非表单格式的请求(如 JSON、XML),需通过输入流直接读取请求体:
| 方法 | 作用描述 |
|---|---|
getInputStream() |
获取请求体的字节输入流(ServletInputStream) |
getReader() |
获取请求体的字符输入流(BufferedReader,需指定编码) |
示例:读取 JSON 请求体
1 | // 设置字符编码 |
会话管理相关方法
HttpServletRequest 提供会话(HttpSession)相关方法,用于跟踪用户状态:
| 方法 | 作用描述 |
|---|---|
getSession() |
获取当前会话,若不存在则创建新会话(等价于 getSession(true)) |
getSession(boolean create) |
若 create=true,不存在则创建;create=false,不存在则返回 null |
getRequestedSessionId() |
获取请求中携带的会话 ID(从 Cookie 或 URL 中提取) |
isRequestedSessionIdValid() |
判断请求中的会话 ID 是否有效(对应会话是否存在) |
changeSessionId() |
更换当前会话的 ID(用于防止会话固定攻击) |
示例:获取会话并存储用户信息
1 | HttpSession session = request.getSession(); |
其他常用方法
| 方法 | 作用描述 |
|---|---|
getCookies() |
获取请求中的所有 Cookie(返回 Cookie[]) |
getAuthType() |
获取认证方式(如 BASIC、FORM) |
getRemoteUser() |
获取通过认证的用户名(如 HTTP 基本认证) |
isUserInRole(String role) |
判断当前用户是否属于指定角色(用于权限控制) |
getParts() / getPart(String name) |
处理文件上传(获取请求中的 multipart 部分,需 @MultipartConfig 注解) |
注意事项
- 参数编码:
- 对于 URL query 参数,需在服务器配置中指定编码(如 Tomcat 的
URIEncoding="UTF-8"); - 对于 POST 请求体,需在读取参数前调用
request.setCharacterEncoding("UTF-8")。
- 对于 URL query 参数,需在服务器配置中指定编码(如 Tomcat 的
- 参数获取时机:
getParameter()方法会消耗请求体流,调用后getInputStream()或getReader()将返回空流,需注意调用顺序。
- 会话安全性:
- 优先使用 Cookie 存储会话 ID(
isRequestedSessionIdFromCookie()),避免 URL 传参(易泄露)。
- 优先使用 Cookie 存储会话 ID(