JavaWeb 核心:Request 与 Response 对象全解析与实战

在 JavaWeb 开发中,HttpServletRequestHttpServletResponse是处理客户端请求与服务器响应的核心对象,Tomcat 会为每一次 HTTP 请求自动创建对应的 request 和 response 实例,封装请求的所有信息和响应的所有操作。掌握这两个对象的使用,是实现 JavaWeb 交互功能的基础,也是面试中的高频考点。本文将从核心功能、API 实战、乱码处理、请求转发与重定向等方面,全面解析 Request 与 Response 对象,结合实战代码让你快速上手。

一、Tomcat 请求响应模型

Web 服务器的核心请求响应流程可概括为:

  1. 客户端向 Tomcat 服务器发送 HTTP 请求(GET/POST 等);
  2. Tomcat 针对每一次请求 单独创建HttpServletRequest(请求对象)和HttpServletResponse(响应对象);
  3. 开发者通过request对象获取客户端提交的所有数据(请求头、请求参数、URL 信息等);
  4. 开发者通过response对象向客户端输出数据(响应头、响应正文、状态码等);
  5. 请求响应完成后,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-AgentReferer);
  • 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 获取请求参数(重点 / 精通)

请求参数是客户端向服务器传递的核心数据,传递方式分为GETPOST,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()方法无效,有两种解决方式:

  1. 手动转码:与 POST 兼容方案一致,对每个中文参数单独转码;
  2. 配置 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);

请求转发的特点

  1. 地址栏 URL不发生变化
  2. 整个过程属于一次请求,request 域数据可共享;
  3. 只能转发到当前项目内部的资源,不能跨域;
  4. 转发效率更高,因为无需客户端重新发送请求。

三、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):设置正常状态码(如200302);
  • 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");

重定向的特点

  1. 地址栏 URL会发生变化,显示新的资源地址;
  2. 整个过程属于两次请求 ,第一次请求的 request 域数据失效
  3. 可以重定向到任意域名的资源,支持跨域;
  4. 重定向效率略低,因为需要客户端重新发送请求。

四、请求转发与重定向的区别(面试必问)

请求转发(forward)和重定向(redirect)是 JavaWeb 中两种页面跳转方式,也是面试高频考点,核心区别可从处理流程、地址栏、请求次数、数据共享、跨域、路径六个维度总结,下表为详细对比:

开发选型建议

  1. 若需要在跳转过程中传递数据 (如登录结果、查询数据),使用请求转发
  2. 若需要跳转到外部网站 ,或跳转后避免用户重复提交表单 (如提交后重定向),使用重定向
  3. 项目内部无数据传递的跳转,可根据需求任选,推荐请求转发(效率更高)。

五、核心学习目标与开发注意事项

5.1 核心学习目标

  1. 熟练使用 request 的 API 获取单值 / 多值请求参数,解决实际开发中的参数传递问题;
  2. 快速定位并解决GET/POST 请求中文乱码、响应中文乱码问题,避免开发中的乱码坑;
  3. 熟练使用请求转发 实现服务器内部跳转并传递数据,使用重定向实现跨域 / 无数据跳转;
  4. 精准区分请求转发和重定向的区别,能在面试中流畅回答,在开发中合理选型;
  5. 掌握绝对路径 / 相对路径的使用规则,解决项目中常见的404 资源找不到问题。

5.2 开发注意事项

  1. request.setCharacterEncoding()必须在获取参数前调用,否则乱码处理无效;
  2. response.setContentType()必须在获取输出流前调用,否则响应乱码处理无效;
  3. 请求转发的forward()方法调用后,后续代码仍会执行,建议添加return终止代码;
  4. 尽量避免使用 GET 请求传递中文参数,减少乱码问题;
  5. Tomcat8.5 + 已默认支持 URL 中文 UTF-8 编码,无需手动配置URIEncoding
  6. request 域对象的作用范围仅为一次请求,切勿用于跨请求的数据传递(需用 session)。

推荐收藏,方便开发中快速查阅 API 和解决问题!如果本文对你有帮助,欢迎点赞、评论、转发~

相关推荐
j7~15 天前
【Linux】基础IO超万字解析(文件描述符)(2)
linux·运维·服务器·c++·file·重定向·文件描述
初学小白...17 天前
JavaWeb
javaweb·web
老四啊laosi18 天前
【Linux系统】18. 基础IO(文件管理部分)
linux·文件操作·重定向
一只大袋鼠18 天前
SpringMVC 框架中的拦截器
java·springmvc·javaweb·拦截器
一只大袋鼠19 天前
SpringMVC全局异常处理
java·开发语言·springmvc·javaweb
一只大袋鼠21 天前
JavaWeb四种文件上传方式(下篇)
java·开发语言·springmvc·javaweb
一只大袋鼠21 天前
JavaWeb四种文件上传方式(上篇)
java·开发语言·servlet·javaweb
abcnull1 个月前
传统的JavaWeb项目Demo快速学习!
java·servlet·elementui·vue·javaweb
float_com1 个月前
【JavaWeb】----- 登录认证 与 统一拦截架构详解
javaweb
float_com2 个月前
【JavaWeb】----- Linux基础入门
linux·javaweb