HttpServletRequest 对象包含了哪些信息?
HttpServletRequest
对象是由 Servlet 容器创建的,它封装了来自客户端(通常是浏览器)的 HTTP 请求的所有信息。当容器调用 Servlet 的 service()
方法(进而调用 doGet()
, doPost()
等)时,这个对象会作为参数传递进来。
HttpServletRequest
对象包含了以下主要方面的信息:
-
请求行 (Request Line) 信息:
- HTTP 方法 (GET, POST, PUT, DELETE 等)
- 请求的 URI (Uniform Resource Identifier)
- HTTP 协议版本
-
请求头 (Request Headers):
- 例如
User-Agent
,Accept
,Accept-Language
,Cookie
,Host
,Content-Type
,Content-Length
等。
- 例如
-
请求参数 (Request Parameters):
- 通常来自 URL 的查询字符串 (query string) 或 HTML 表单提交的数据 (application/x-www-form-urlencoded 或 multipart/form-data)。
-
请求体 (Request Body / Message Body):
- 对于 POST 或 PUT 请求,请求体通常包含要发送到服务器的数据(如表单数据、JSON、XML、文件上传等)。
-
Cookies:
- 客户端随请求发送过来的 Cookie 信息。
-
会话 (Session) 信息:
- 与当前请求关联的
HttpSession
对象,用于跨多个请求跟踪用户状态。
- 与当前请求关联的
-
客户端和服务器信息:
- 客户端的 IP 地址、主机名、端口号。
- 服务器的 IP 地址、主机名、端口号。
- 协议 (http/https)
-
路径信息:
- 上下文路径 (Context Path)、Servlet 路径 (Servlet Path)、路径信息 (Path Info)。
-
属性 (Attributes):
- 在请求处理期间,可以在服务器端存储和检索与请求相关的对象。这些属性只在当前请求的生命周期内有效,常用于 Servlet 之间通过
RequestDispatcher
转发请求时传递数据。
- 在请求处理期间,可以在服务器端存储和检索与请求相关的对象。这些属性只在当前请求的生命周期内有效,常用于 Servlet 之间通过
下面是如何从 HttpServletRequest
对象中获取这些信息的常用方法:
1. 获取请求参数 (Request Parameters)
参数通常来自 URL 的查询字符串(如 ?name=value&name2=value2
)或 HTML 表单提交的数据。
-
String getParameter(String name)
:
返回指定请求参数的单个值。如果参数不存在,返回null
。如果参数有多个值,它通常返回第一个值(具体行为可能因容器而异,但一般是第一个)。String username = request.getParameter("username"); // <input type="text" name="username"> String productId = request.getParameter("id"); // from URL: /products?id=123
-
String[] getParameterValues(String name)
:
返回指定请求参数的所有值组成的字符串数组。如果参数不存在,返回null
。这对于处理具有相同名称的多个输入字段(例如多选列表或复选框)非常有用。String[] hobbies = request.getParameterValues("hobby"); // <input type="checkbox" name="hobby" value="reading">// <input type="checkbox" name="hobby" value="coding"> if (hobbies != null) {for (String hobby : hobbies) {System.out.println("Hobby: " + hobby);} }
-
java.util.Enumeration<String> getParameterNames()
:
返回请求中所有参数名称的Enumeration
对象。 -
java.util.Map<String, String[]> getParameterMap()
:
返回请求中所有参数的Map
,其中键是参数名 (String),值是该参数名对应的所有值的字符串数组 (String[]
)。
重要提示 (处理 POST 请求的字符编码):
如果请求是 POST 请求,并且请求体是 application/x-www-form-urlencoded
类型(HTML 表单默认),那么在第一次调用任何 getParameterXXX()
方法 之前,你应该设置请求的字符编码,以确保非 ASCII 字符能被正确解析:
request.setCharacterEncoding("UTF-8"); // 必须在第一次 getParameter() 之前调用
String comments = request.getParameter("comments");
对于 GET 请求,查询字符串的编码通常由容器根据服务器配置(例如 Tomcat 的 server.xml
中的 URIEncoding
或 useBodyEncodingForURI
)处理。
2. 获取请求头 (Request Headers)
-
String getHeader(String name)
:
返回指定请求头的值。头名称不区分大小写。如果请求没有包含该头,返回null
。String userAgent = request.getHeader("User-Agent"); String contentType = request.getHeader("Content-Type");
-
java.util.Enumeration<String> getHeaders(String name)
:
返回指定请求头的所有值组成的Enumeration
对象。有些头可以有多个值。 -
java.util.Enumeration<String> getHeaderNames()
:
返回此请求中包含的所有头名称的Enumeration
。 -
int getIntHeader(String name)
:
便捷方法,获取指定头的值并将其转换为int
。如果头不存在或无法转换为整数,则返回 -1。 -
long getDateHeader(String name)
:
便捷方法,获取指定头的值并将其解析为表示日期/时间的long
值(自 epoch 以来的毫秒数)。如果头不存在或无法解析,则返回 -1。
3. 获取 Cookies
javax.servlet.http.Cookie[] getCookies()
:
返回一个包含此请求发送的所有Cookie
对象的数组。如果请求没有发送任何 Cookie,则返回null
(而不是空数组)。Cookie[] cookies = request.getCookies(); String sessionId = null; if (cookies != null) {for (Cookie cookie : cookies) {if ("JSESSIONID".equals(cookie.getName())) {sessionId = cookie.getValue();System.out.println("Session ID from cookie: " + sessionId);}if ("username".equals(cookie.getName())) {String user = cookie.getValue();System.out.println("Username from cookie: " + user);}} }
4. 获取 Session 信息
会话允许你在用户的多个请求之间跟踪信息。
-
HttpSession getSession()
:
返回与此请求关联的当前会话。如果当前请求没有会话,则创建一个新的会话并返回。等同于getSession(true)
。 -
HttpSession getSession(boolean create)
:- 如果
create
为true
:返回与此请求关联的当前会话。如果请求还没有会话,则创建一个新的会话并返回。 - 如果
create
为false
:返回与此请求关联的当前会话。如果请求还没有会话,则返回null
(不会创建新会话)。
// 获取现有会话,如果不存在则创建一个 HttpSession session = request.getSession(); // 或 request.getSession(true);// 获取现有会话,如果不存在则不创建 (返回 null) // HttpSession existingSession = request.getSession(false); // if (existingSession == null) { // System.out.println("No existing session for this request."); // }// 从会话中获取属性 String username = (String) session.getAttribute("loggedInUser"); if (username != null) {System.out.println("User from session: " + username); } else {// 将属性存入会话session.setAttribute("loggedInUser", "Alice");System.out.println("Stored user 'Alice' in session."); }// 其他会话操作: // session.removeAttribute("attributeName"); // 移除属性 // session.invalidate(); // 使会话失效 // String sessionId = session.getId(); // 获取会话 ID // boolean isNew = session.isNew(); // 检查会话是否是新创建的
- 如果
5. 获取请求体 (Request Body)
主要用于 POST, PUT 等方法。
-
java.io.BufferedReader getReader()
:
以字符流的形式检索请求的主体。在使用此方法读取前,通常需要通过request.setCharacterEncoding()
设置正确的字符编码。// 假设请求体是 JSON 或 XML 文本 // request.setCharacterEncoding("UTF-8"); // 确保在 getReader 之前设置 // StringBuilder sb = new StringBuilder(); // String line; // try (BufferedReader reader = request.getReader()) { // while ((line = reader.readLine()) != null) { // sb.append(line); // } // } // String requestBody = sb.toString(); // System.out.println("Request Body: " + requestBody);
-
javax.servlet.ServletInputStream getInputStream()
:
以二进制字节流的形式检索请求的主体。用于处理非文本数据,如文件上传(尽管对于文件上传,通常使用更高级的 API,如 Servlet 3.0+ 的request.getPart()
或 Apache Commons FileUpload)。// ServletInputStream inputStream = request.getInputStream(); // // ... 读取字节数据 ...
注意:
getReader()
和getInputStream()
只能调用其中一个,且只能调用一次。如果请求体已被getParameterXXX()
方法读取(例如application/x-www-form-urlencoded
POST),则可能无法再通过这些方法读取。
6. 获取请求 URL/路径信息
String getMethod()
: 返回 HTTP 方法 (GET, POST, etc.)。String getRequestURI()
: 返回 HTTP 请求行中从协议名到查询字符串之间的部分 (e.g.,/myapp/myservlet/pathinfo
)。StringBuffer getRequestURL()
: 返回客户端用于发出请求的完整 URL (e.g.,http://www.example.com/myapp/myservlet/pathinfo
)。String getContextPath()
: 返回 Web 应用的上下文路径 (e.g.,/myapp
)。如果应用是根上下文,则返回空字符串""
。String getServletPath()
: 返回调用 Servlet 的路径部分,相对于上下文路径 (e.g.,/myservlet
if URL pattern is/myservlet/*
)。String getPathInfo()
: 返回客户端请求中 Servlet 路径之后、查询字符串之前的部分 (e.g.,/pathinfo
if request URI is/myapp/myservlet/pathinfo
and servlet path is/myservlet
)。如果没有额外路径信息,则返回null
。String getQueryString()
: 返回 URL 中 “?” 之后的部分,即查询参数字符串。如果 URL 没有查询字符串,则返回null
。
7. 获取客户端和服务器信息
String getRemoteAddr()
: 返回发送请求的客户端的 IP 地址。String getRemoteHost()
: 返回发送请求的客户端的完全限定域名 (FQDN),如果无法解析则返回 IP 地址。int getRemotePort()
: 返回客户端发送请求时使用的 TCP 端口号。String getLocalAddr()
: 返回服务器接收请求的网络接口的 IP 地址。String getLocalName()
: 返回服务器接收请求的网络接口的主机名。int getServerPort()
: 返回服务器接收请求的端口号。String getScheme()
: 返回请求使用的协议方案 (e.g., “http”, “https”)。boolean isSecure()
: 如果请求是通过安全通道 (如 HTTPS) 发送的,则返回true
。
8. 获取/设置属性 (Attributes)
属性是在服务器端与请求关联的数据,它们的作用域仅限于当前请求。常用于 Servlet 之间通过 RequestDispatcher
进行转发时传递数据。
Object getAttribute(String name)
: 返回具有给定名称的属性值,如果不存在则返回null
。void setAttribute(String name, Object o)
: 将一个对象以给定的名称存储在此请求中。void removeAttribute(String name)
:从此请求中移除具有给定名称的属性。java.util.Enumeration<String> getAttributeNames()
: 返回此请求中可用的所有属性名称的Enumeration
。
// 在一个 Servlet 中设置属性
request.setAttribute("userInfo", new User("John Doe", 30));// 通过 RequestDispatcher 转发到另一个 Servlet 或 JSP
// RequestDispatcher dispatcher = request.getRequestDispatcher("/anotherServlet");
// dispatcher.forward(request, response);// 在另一个 Servlet (或 JSP) 中获取属性
// User user = (User) request.getAttribute("userInfo");
// if (user != null) {
// System.out.println("User from attribute: " + user.getName());
// }
HttpServletRequest
对象是 Servlet 开发的核心,它提供了客户端请求的所有入口。