转发和重定向
在 Java Web 开发中,转发 (Forward) 和 重定向 (Redirect) 是实现页面跳转的两种核心机制。虽然结果都是“看到新页面”,但它们的底层原理完全不同。
1. 转发 (Forward)
转发是服务器内部的行为。就像你给公司总机打电话找张三,接线员没挂电话直接把线转给了张三。
- 代码实现:
request.getRequestDispatcher("/dest").forward(request, response); - 请求次数: 只有 1次 请求。客户端发送请求后,服务器内部转交给另一个资源处理。
- 地址栏: 不会改变。浏览器并不知道服务器内部做了跳转,地址栏显示的还是初始路径。
- 数据共享: 共享 Request 域。因为是同一次请求,存放在
request.setAttribute()中的数据在目标页面依然能取到。 - 范围限制: 只能转发到当前 Web 应用内部的资源。
2. 重定向 (Redirect)
重定向是**客户端(浏览器)**的行为。就像你给公司总机打过去,接线员告诉你:“张三搬家了,请拨打另一个号码 12345”,于是你挂断电话,重新拨打了新号码。
- 代码实现:
response.sendRedirect("/dest"); - 请求次数: 共有 2次 请求。第一次请求返回 302 状态码和新地址,浏览器自动发起第二次请求。
- 地址栏: 会改变。地址栏会更新为第二次请求的新 URL。
- 数据共享: 不共享 Request 域。由于是两次完全独立的请求,第一次请求中的数据会丢失(除非存在 Session 中)。
- 范围限制: 可以跳转到任何地方,包括外部网站(如
http://www.google.com)。
3. 核心差异对比表
| 特性 | 转发 (Forward) | 重定向 (Redirect) |
|---|---|---|
| 发生位置 | 服务器端内部 | 浏览器端 |
| 地址栏变化 | 不变 | 变化 |
| HTTP 请求数 | 1次 | 2次 |
| 数据传递 | 可以通过 Request 域传值 | 无法通过 Request 传值 |
| 跳转范围 | 仅限本应用 | 任意 URL |
| 效率 | 较高(减少了网络往返) | 较低(多一次网络请求) |
4. 什么时候用哪种?
- 使用转发的场景:
- 登录成功后跳转到主页(且需要传递用户信息)。
- Servlet 处理完逻辑后,把数据交给 JSP 页面进行展示。
- 使用重定向的场景:
- 防止表单重复提交: 用户提交订单后,重定向到成功页面。这样用户刷新页面时,刷新的只是成功页,不会再次触发订单提交请求。
- 注销登录后跳转到登录页面。
- 跳转到站外链接。