在 JavaWeb 开发中,HttpServletRequest 和HttpServletResponse是处理客户端请求与服务器响应的核心对象,Tomcat 会为每一次 HTTP 请求自动创建对应的 request 和 response 实例,封装请求的所有信息和响应的所有操作。掌握这两个对象的使用,是实现 JavaWeb 交互功能的基础,也是面试中的高频考点。本文将从核心功能、API 实战、乱码处理、请求转发与重定向等方面,全面解析 Request 与 Response 对象,结合实战代码让你快速上手。
一、Tomcat 请求响应模型
Web 服务器的核心请求响应流程可概括为:
- 客户端向 Tomcat 服务器发送 HTTP 请求(GET/POST 等);
- Tomcat 针对每一次请求 单独创建
HttpServletRequest(请求对象)和HttpServletResponse(响应对象); - 开发者通过
request对象获取客户端提交的所有数据(请求头、请求参数、URL 信息等); - 开发者通过
response对象向客户端输出数据(响应头、响应正文、状态码等); - 请求响应完成后,Tomcat 销毁本次的 request 和 response 对象。
简单来说:取数据找 request,回数据找 response。
二、HttpServletRequest 核心功能与实战
HttpServletRequest是 Servlet 的service()方法核心参数之一,其核心功能可分为四类:封装请求头、封装请求参数、作为域对象存储数据、实现请求转发。下面按开发使用频率依次讲解核心 API。
2.1 获取请求相关基础信息
request 提供了一系列方法获取请求的 URL、方法、客户端信息等,常用于请求日志、权限校验等场景,核心方法如下(结合示例 URL:http://localhost:8080/hello/oneServlet?name=zhangSan):
java
// 打印请求基础信息
System.out.println("请求方法: " + request.getMethod());
System.out.println("项目上下文: " + request.getContextPath());
System.out.println("客户端IP: " + request.getRemoteAddr());
System.out.println("完整URL: " + request.getRequestURL());
2.2 获取请求头数据
请求头封装了客户端的浏览器信息、请求格式、缓存策略等,核心方法为:
String getHeader(String name):根据请求头名称获取对应值(如User-Agent、Referer);Enumeration getHeaderNames():获取所有请求头名称,遍历获取全部请求头。
实战代码:获取并打印所有请求头
java
// 设置响应编码,避免前端乱码
response.setContentType("text/html;charset=utf-8");
// 获取所有请求头名称
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String value = request.getHeader(name);
System.out.println(name + ": " + value); // 控制台打印
response.getWriter().println(name + ": " + value + "<br/>"); // 前端页面打印
}
2.3 获取请求参数(重点 / 精通)
请求参数是客户端向服务器传递的核心数据,传递方式分为GET 和POST,request 提供了统一的 API 获取参数,无需区分请求方式(乱码处理单独解决)。
2.3.1 两种参数传递方式
- GET 请求 :参数拼接在 URL 后(
?k1=v1&k2=v2),可通过地址栏、超链接、GET 方式表单提交,参数有长度限制; - POST 请求:参数封装在请求正文中,可通过 POST 方式表单、Ajax 提交,无长度限制,安全性更高。
2.3.2 核心获取参数方法

2.3.3 单值参数实战
前台 POST 表单:
java
<form action="ParamServlet" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="pwd"/><br/>
<input type="submit" value="提交"/>
</form>
后台 Servlet 接收:
java
// 直接获取单值参数
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
// 遍历所有参数
Enumeration<String> paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
String value = request.getParameter(name);
System.out.println(name + " = " + value);
}
// 批量获取参数Map
Map<String, String[]> paramMap = request.getParameterMap();
for (String key : paramMap.keySet()) {
String[] values = paramMap.get(key);
System.out.println(key + " : " + Arrays.toString(values));
}
2.3.4 多值参数实战(复选框)
前台复选框表单:
java
<form action="ParamServlet" method="post">
爱好:<br/>
上网:<input type="checkbox" name="hobby" value="netplay"/><br/>
踢球:<input type="checkbox" name="hobby" value="football"/><br/>
看书:<input type="checkbox" name="hobby" value="read"/><br/>
<input type="submit" value="提交"/>
</form>
后台 Servlet 接收:
java
// 获取多值参数数组
String[] hobbies = request.getParameterValues("hobby");
// 判空后打印
if (hobbies != null) {
System.out.println("爱好:" + Arrays.toString(hobbies));
}
2.4 中文乱码处理(重点 / 熟练)
由于 Tomcat 默认使用ISO-8859-1编码解析请求参数,而项目中通常使用UTF-8,因此会出现中文乱码,GET 和 POST 请求的乱码处理方式不同,需分别解决。
2.4.1 POST 请求中文乱码
POST 请求参数在请求正文中,可通过request.setCharacterEncoding("UTF-8")直接设置请求编码,该方法必须在所有getParameter()方法之前调用。
推荐方案:
java
// 设置请求编码为UTF-8,仅对POST正文有效
request.setCharacterEncoding("UTF-8");
// 后续获取参数无乱码
String username = request.getParameter("username");
兼容方案(手动转码):若未设置请求编码,可通过字节数组手动转码
java
String username = request.getParameter("username");
// 先按ISO-8859-1取字节,再按UTF-8转字符串
username = new String(username.getBytes("ISO-8859-1"), "UTF-8");
2.4.2 GET 请求中文乱码
GET 请求参数在 URL 中,无请求正文,setCharacterEncoding()方法无效,有两种解决方式:
- 手动转码:与 POST 兼容方案一致,对每个中文参数单独转码;
- 配置 Tomcat :在 Tomcat 的
conf/server.xml中为 Connector 添加URIEncoding="UTF-8",全局生效。
Tomcat 配置方案:
java
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
注意:Tomcat8.5 及以上版本已默认支持 URL 中文 UTF-8 编码,无需手动配置!开发建议:尽量避免使用 GET 请求传递中文参数,减少乱码问题。
2.5 请求转发与 request 域对象(重点 / 熟练)
2.5.1 request 域对象
request 是域对象 ,可将数据存储在其中,作用范围为一次请求响应之内(即请求转发的整个过程),核心方法:
void setAttribute(String name, Object value):向域中存储数据;Object getAttribute(String name):从域中获取数据;void removeAttribute(String name):从域中删除数据。
与 ServletContext 域对象相比,request 域的作用范围更小,仅针对本次请求,避免了数据污染,是请求转发中传递数据的最佳方式。
2.5.2 请求转发
请求转发是服务器内部的页面跳转,由 Servlet 将请求转发给其他资源(JSP/HTML/Servlet),核心方法:
java
// 存储数据到request域
request.setAttribute("msg", "登录成功!");
// 执行请求转发,跳转到success.jsp
request.getRequestDispatcher("/success.jsp").forward(request, response);
请求转发的特点:
- 地址栏 URL不发生变化;
- 整个过程属于一次请求,request 域数据可共享;
- 只能转发到当前项目内部的资源,不能跨域;
- 转发效率更高,因为无需客户端重新发送请求。
三、HttpServletResponse 核心功能与实战
HttpServletResponse用于向客户端响应请求,封装了响应头、响应正文、状态码等信息,核心功能分为四类:设置响应头、发送状态码、设置响应正文、实现重定向。
3.1 响应中文乱码处理(前提)
与 request 类似,response 向客户端输出中文时,默认使用ISO-8859-1编码,需先设置响应编码,必须在获取输出流(getWriter())之前调用。
推荐配置:
java
// 一次性设置响应内容类型和编码,推荐使用
response.setContentType("text/html;charset=utf-8");
// 单独设置响应编码(可省略,上述方法已包含)
// response.setCharacterEncoding("UTF-8");
// 获取字符输出流
PrintWriter out = response.getWriter();
// 输出中文无乱码
out.write("您好,JavaWeb!");
3.2 设置状态码与错误提示
状态码代表服务器的响应结果,常见的有200(成功)、404(资源不存在)、500(服务器内部错误),核心方法:
void setStatus(int sc):设置正常状态码(如200、302);void sendError(int sc, String msg):发送错误状态码,并携带错误提示信息。
实战代码:
java
// 发送404错误,提示资源不存在
response.sendError(404, "您访问的资源不存在,请检查URL!");
// 设置200成功状态码(默认,可省略)
response.setStatus(200);
3.3 设置响应头
响应头用于告诉客户端如何处理响应数据(如刷新、缓存、重定向),核心方法:
void setHeader(String name, String value):设置指定名称的响应头;void addHeader(String name, String value):添加响应头(避免覆盖原有值)。
常用实战场景:定时刷新 / 重定向
java
// 5秒后自动刷新当前页面
response.setHeader("Refresh", "5");
// 5秒后自动跳转到百度首页
response.setHeader("Refresh", "5;URL=http://www.baidu.com");
3.4 重定向(重点 / 熟练)
重定向是服务器通知客户端重新发送请求到新的资源,核心方法:
java
// 重定向到项目内的fail.html
response.sendRedirect("/hello/fail.html");
// 重定向到外部域名(百度)
response.sendRedirect("http://www.baidu.com");
重定向的特点:
- 地址栏 URL会发生变化,显示新的资源地址;
- 整个过程属于两次请求 ,第一次请求的 request 域数据失效;
- 可以重定向到任意域名的资源,支持跨域;
- 重定向效率略低,因为需要客户端重新发送请求。
四、请求转发与重定向的区别(面试必问)
请求转发(forward)和重定向(redirect)是 JavaWeb 中两种页面跳转方式,也是面试高频考点,核心区别可从处理流程、地址栏、请求次数、数据共享、跨域、路径六个维度总结,下表为详细对比:

开发选型建议:
- 若需要在跳转过程中传递数据 (如登录结果、查询数据),使用请求转发;
- 若需要跳转到外部网站 ,或跳转后避免用户重复提交表单 (如提交后重定向),使用重定向;
- 项目内部无数据传递的跳转,可根据需求任选,推荐请求转发(效率更高)。
五、核心学习目标与开发注意事项
5.1 核心学习目标
- 熟练使用 request 的 API 获取单值 / 多值请求参数,解决实际开发中的参数传递问题;
- 快速定位并解决GET/POST 请求中文乱码、响应中文乱码问题,避免开发中的乱码坑;
- 熟练使用请求转发 实现服务器内部跳转并传递数据,使用重定向实现跨域 / 无数据跳转;
- 精准区分请求转发和重定向的区别,能在面试中流畅回答,在开发中合理选型;
- 掌握绝对路径 / 相对路径的使用规则,解决项目中常见的404 资源找不到问题。
5.2 开发注意事项
request.setCharacterEncoding()必须在获取参数前调用,否则乱码处理无效;response.setContentType()必须在获取输出流前调用,否则响应乱码处理无效;- 请求转发的
forward()方法调用后,后续代码仍会执行,建议添加return终止代码; - 尽量避免使用 GET 请求传递中文参数,减少乱码问题;
- Tomcat8.5 + 已默认支持 URL 中文 UTF-8 编码,无需手动配置
URIEncoding; - request 域对象的作用范围仅为一次请求,切勿用于跨请求的数据传递(需用 session)。
推荐收藏,方便开发中快速查阅 API 和解决问题!如果本文对你有帮助,欢迎点赞、评论、转发~