JavaWeb 核心:HttpServletRequest 请求行、请求头、请求参数完整梳理
在 JavaWeb 的 HttpServletRequest 对象中,请求行、请求头、请求参数 是封装客户端 HTTP 请求的三大核心部分,对应 HTTP 协议请求报文的不同组成区域。下面逐一拆解这三个参数的定义、获取方式、应用场景及注意事项:
一、请求行(Request Line)
1. 定义
请求行是 HTTP 请求报文的第一行,包含 请求方法、请求路径、协议版本 三个核心要素,
格式为:
请求方法 + 请求URI + HTTP协议版本
示例:
GET /user?username=zhangsan HTTP/1.1
2. 核心组成 & 获取方法
| 组成部分 | 说明 | HttpServletRequest 获取方法 |
|---|---|---|
| 请求方法 | 客户端告知服务器要执行的操作(GET/POST/PUT/DELETE 等) | String getMethod()(返回 GET/POST 等字符串) |
| 请求 URI/URL | 客户端要访问的服务器资源路径(含参数) | - String getRequestURI():仅路径(如 /user)- String getRequestURL():完整 URL(如 http://localhost:8080/user)- String getQueryString():URL 后参数(如 username=zhangsan) |
| 协议版本 | HTTP 协议版本(如 HTTP/1.1) | String getProtocol() |
补充:
常见的请求方式:
| 方法 | 中文名称 | 核心语义 | 典型应用场景 | 关键特点 |
|---|---|---|---|---|
| GET | 获取 | 从服务器读取 / 查询资源 | 页面访问、商品列表查询、参数拼接在 URL 中 | 1. 幂等(多次请求结果一致); 2. 可缓存; 3. 参数在 URL(长度有限) ;4. 无请求体 |
| POST | 提交 | 向服务器提交数据,创建资源 | 表单提交(登录 / 注册)、文件上传、提交 JSON 数据 | 1. 非幂等(多次提交可能创建多份资源); 2. 参数在请求体(无长度限制); 3. 不可缓存 |
| PUT | 更新 | 全量更新服务器上的资源 | 修改用户信息(全字段更新)、替换订单数据 | 1. 幂等; 2. 需指定资源唯一标识(如 /user/1); 3. 无则创建、有则全量覆盖 |
| DELETE | 删除 | 删除服务器上的指定资源 | 删除订单、删除用户、删除文件 | 1. 幂等; 2. 需指定资源唯一标识; 3. 通常无请求体 |
| OPTIONS | 预检 | 询问服务器支持的请求方法 / 头 | 跨域请求前的预检(如前端发 PUT/DELETE 请求时) | 1. 无业务逻辑; 2. 服务器需返回允许的方法 / 头; 3. 仅做「试探」不处理数据 |
| HEAD | 头信息 | 仅获取响应头,不返回响应体 | 检查资源是否存在、获取文件大小 / 更新时间 | 1. 与 GET 语义一致; 2. 响应无体; 3. 可用于缓存校验 |
| TRACE | 追踪 | 回显服务器收到的请求,用于调试 | 排查请求传输过程中的问题(如代理转发) | 1. 极少使用; 2. 存在安全风险(易被 XSS 利用); 3. 生产环境通常禁用 |
| CONNECT | 隧道 | 建立隧道连接(如 HTTPS 代理) | 代理服务器转发 HTTPS 请求 | 1. 仅用于代理场景; 2. 普通 Web 开发几乎不用 |
解释一下:
幂等性:多次执行同一请求,结果与执行一次完全一致(不会产生额外副作用);
简单举个实例:
你去ATM 机取钱 100 元:取 1 次余额少 100,变成 4900;如果因为网络卡了,你重复点了「确认取钱」,点 2 次就会被扣 200,点 3 次扣 300,余额会变、产生了额外副作用,这个「取钱」操作就是 非幂等的。
3. 应用场景
- 判断请求类型:如
if (request.getMethod().equals("POST"))区分 GET/POST 请求,执行不同逻辑; - 日志记录:记录客户端访问的完整路径和请求方式,用于系统审计;
- 路径匹配:通过
getRequestURI()实现自定义请求路由。
示例代码
java
// 获取请求行信息
String method = request.getMethod(); // 输出:GET
String uri = request.getRequestURI(); // 输出:/user
String url = request.getRequestURL().toString(); // 输出:http://localhost:8080/user
String queryString = request.getQueryString(); // 输出:username=zhangsan
String protocol = request.getProtocol(); // 输出:HTTP/1.1
System.out.println("请求方法:" + method + ",请求路径:" + uri + ",协议版本:" + protocol);
二、请求头(Request Headers)
1. 定义
请求头是请求行之后、请求体之前的键值对集合,用于传递客户端环境、请求附加信息(如浏览器类型、字符编码、Cookie 等),格式为:Header-Name: Header-Value示例:
plaintext
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0
Cookie: JSESSIONID=123456789; username=zhangsan
Content-Type: application/x-www-form-urlencoded
2. 核心常用请求头 & 获取方法
| 常用请求头 | 说明 | HttpServletRequest 获取方法 |
|---|---|---|
| User-Agent | 客户端浏览器 / 设备信息(用于判断客户端类型) | String getHeader("User-Agent") |
| Cookie | 客户端存储的会话标识 / 用户信息 | String getHeader("Cookie") |
| Content-Type | 请求体的类型(如表单 application/x-www-form-urlencoded、JSON application/json) |
String getContentType() |
| Accept | 客户端可接收的响应数据类型(如 text/html、application/json) |
String getHeader("Accept") |
| Referer | 客户端跳转前的页面地址(用于防盗链、统计来源) | String getHeader("Referer") |
3. 批量获取请求头
java
// 获取所有请求头名称
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
System.out.println(headerName + ": " + headerValue);
}
4. 应用场景
- 防盗链:通过
Referer判断请求是否来自合法域名; - 客户端适配:通过
User-Agent区分 PC / 移动端,返回不同页面; - 编码处理:结合
Content-Type判断请求体编码格式; - 会话跟踪:通过
Cookie头获取 JSESSIONID,关联用户 Session。
三、请求参数(Request Parameters)
1. 定义
请求参数是客户端传递给服务器的键值对数据,主要有两种传递方式:
-
GET 请求:拼接在 URL 后(如
?username=zhangsan&age=20); -
POST 请求:放在请求体(Request Body)中(如表单提交、JSON 数据);
核心特点:参数以key=value形式存在,支持单个 key 对应多个 value(如复选框)。
2. 获取方法
| 方法 | 说明 |
|---|---|
String getParameter(String name) |
获取单个参数值(最常用),若参数不存在返回 null |
String[] getParameterValues(String name) |
获取多个参数值(如复选框 hobby=game&hobby=book) |
Map<String, String[]> getParameterMap() |
获取所有参数的键值对集合(批量处理参数) |
Enumeration<String> getParameterNames() |
获取所有参数名 |
3. 关键注意事项
(1)中文乱码问题
GET 请求:参数拼接在 URL 中,乱码由 Tomcat 默认编码(ISO-8859-1)导致,解决方式:
① Tomcat 配置文件server.xml中添加URIEncoding="UTF-8":
② 手动转码:
String username = new String(request.getParameter("username").getBytes("ISO-8859-1"), "UTF-8");
POST 请求:参数在请求体中,乱码解决方式:request.setCharacterEncoding("UTF-8");
(必须在获取参数前执行)
(2)参数类型转换
getParameter() 返回的是字符串,需手动转换为 int/boolean 等类型:
java
String ageStr = request.getParameter("age");
int age = Integer.parseInt(ageStr); // 转换为整数
(3)JSON 参数处理
若客户端传递的是 JSON 格式参数(如 {"username":"zhangsan","age":20}),getParameter() 无法直接获取,需读取请求体:
java
// 读取 JSON 请求体
BufferedReader reader = request.getReader();
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String json = sb.toString(); // 得到完整 JSON 字符串
4. 示例
java
// 1. 获取单个参数
String username = request.getParameter("username"); // 输出:zhangsan
// 2. 处理中文乱码(POST)
request.setCharacterEncoding("UTF-8");
// 3. 获取多个参数(复选框)
String[] hobbies = request.getParameterValues("hobby"); // 输出:[game, book]
// 4. 获取所有参数
Map<String, String[]> paramMap = request.getParameterMap();
for (String key : paramMap.keySet()) {
String[] values = paramMap.get(key);
System.out.println(key + ": " + Arrays.toString(values));
}
5. 应用场景
- 表单提交:获取用户名、密码、手机号等用户输入;
- 接口调用:接收前端传递的查询条件(如分页参数
pageNum=1&pageSize=10); - 批量操作:通过
getParameterMap()统一校验所有参数是否为空。
四、三者核心关联与总结
| 维度 | 请求行 | 请求头 | 请求参数 |
|---|---|---|---|
| 位置 | HTTP 报文第一行 | 请求行后、请求体前 | URL 后(GET)/ 请求体(POST) |
| 核心作用 | 定义请求 "动作 + 路径" | 传递请求附加信息 | 传递业务数据 |
| 获取核心 | 方法 / 路径 / 协议 | 键值对(环境信息) | 键值对(业务数据) |
| 乱码问题 | 仅 GET URL 需处理 | 一般无乱码 | GET/POST 均需处理 |
总结
- 请求行是 "骨架":确定请求的基本方式和访问路径;
- 请求头是 "附加信息":传递客户端环境、会话等非业务数据;
- 请求参数是 "业务核心":传递客户端需要服务器处理的具体数据;
- 三者均通过
HttpServletRequest封装,是 Servlet 处理请求的基础,掌握其获取方式和乱码、类型转换等问题,是 JavaWeb 开发的核心基本功。
附:
HttpServletRequest 生命周期流程图
GET请求
POST请求
PUT/DELETE等
客户端发起HTTP请求
浏览器/Postman/前端Ajax
Tomcat服务器监听端口
80/8080 接收TCP连接
Tomcat解析请求报文
请求行+请求头+请求体
Tomcat创建HttpServletRequest对象
封装所有请求数据
Tomcat创建HttpServletResponse对象
准备响应数据载体
Tomcat匹配对应的Servlet
根据URL映射规则
调用Servlet的service()方法
传入request+response参数
subservice分发请求
调用doGet(request, response)
调用doPost(request, response)
调用对应doXxx方法
业务逻辑处理
1.从request取值
2.业务计算/数据库操作
3.向response写回数据
Servlet处理完成,方法执行结束
Tomcat从response中提取数据
组装HTTP响应报文
Tomcat将响应报文返回客户端
Tomcat销毁request/response对象
本次请求生命周期结束