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 和解决问题!如果本文对你有帮助,欢迎点赞、评论、转发~

相关推荐
一只大袋鼠6 天前
JavaWeb ——Cookie 对象
java·servlet·javaweb·cookie·小蛋糕
一只大袋鼠6 天前
请求转发vs重定向、同源策略与跨域
java·javaweb·同源策略·请求转发·重定向
为美好的生活献上中指19 天前
*Java 沉淀重走长征路*之——《Java Web 应用开发完全指南:从零到企业实战(两万字深度解析)》
java·开发语言·前端·html·javaweb·js
2301_780669861 个月前
MyBatis(配置,增删改查,注解与XML两种开发方式)、SpringBoot配置文件(yml简化properties)
xml·spring boot·mybatis·javaweb
四谎真好看2 个月前
JavaWeb学习笔记(Day14)
笔记·学习·学习笔记·javaweb
四谎真好看2 个月前
JavaWeb学习笔记(Day13)
笔记·学习·学习笔记·javaweb
四谎真好看2 个月前
JavaWeb学习笔记(Day12)
笔记·学习·学习笔记·javaweb
2301_780669862 个月前
Vue(入门配置、常用指令)、Ajax、Axios
前端·vue.js·ajax·javaweb
四谎真好看2 个月前
JavaWeb学习笔记(Day10)
笔记·学习·学习笔记·javaweb