sendRedirect()和forward()方法有什么区别?
前言
在 Java Web 开发中,sendRedirect()
和 forward()
是两种用于页面跳转的方法,它们的本质区别在于 跳转方式 和 是否能共享请求数据。
1. sendRedirect()
(客户端重定向)
概述
sendRedirect()
方法会让服务器返回 HTTP 302 状态码 和 新的 URL,通知浏览器重新请求该 URL。这相当于让客户端发起两次 HTTP 请求,因此 地址栏会发生变化。
定义:
sendRedirect()
方法用于 客户端重定向,让浏览器重新发送请求到一个新的 URL。
语法
response.sendRedirect("https://www.example.com");
特点
✅ 地址栏变化:浏览器的地址栏会更新为新的 URL。
✅ 是两次请求:第一次请求访问 sendRedirect()
,服务器返回 302
,然后浏览器再发送新的请求。
✅请求方式改变:
- 如果原请求是
POST
,则重定向后变为GET
(默认行为)。 - 如果希望保持
POST
请求,需要使用 POST-Redirect-GET(PRG)模式 或307 Temporary Redirect
。
✅ 不能共享 request
作用域的数据(因为是两个不同的请求)。
✅ 用于跳转到外部网站或不同的 Web 应用。
❌ 性能稍差,因为有两次请求,增加了网络开销。
示例:
@WebServlet("/redirectExample")
public class RedirectExample extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.sendRedirect("https://www.baidu.com");
}
}
执行过程
-
客户端请求
http://localhost:8080/redirectExample
。 -
服务器返回
302 Found
,并告知浏览器跳转到https://www.baidu.com
。 -
浏览器重新发起请求,访问
https://www.baidu.com
。
2. forward()
(服务器端请求转发)
概述
forward()
方法是在 服务器端 内部完成跳转,浏览器不会感知跳转,因此 地址栏不会发生变化,请求仍然是同一个。
定义
forward()
方法用于 服务器端请求转发,将请求转发到 同一个 Web 应用的另一个资源
语法
RequestDispatcher dispatcher = request.getRequestDispatcher("newPage.jsp");
dispatcher.forward(request, response);
特点
✅ 地址栏不变:用户访问的 URL 仍然是原来的地址。
✅ 是一次请求,请求对象 (request
) 和响应 (response
) 可以共享数据。
✅ 只能转发到同一个 Web 应用的资源(不能跳转到外部网站)。
✅ 性能更好,不需要客户端发起二次请求。
❌ 不适用于跨域或跨应用跳转。
示例
@WebServlet("/forwardExample")
public class ForwardExample extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("message", "Hello, this is a forwarded request!");
RequestDispatcher dispatcher = request.getRequestDispatcher("newPage.jsp");
dispatcher.forward(request, response);
}
}
执行过程
-
客户端请求
http://localhost:8080/forwardExample
。 -
服务器内部转发请求到
newPage.jsp
,但地址栏仍显示forwardExample
。 -
newPage.jsp
可以使用request.getAttribute("message")
读取共享数据。
3. sendRedirect()
vs. forward()
总结对比
特性 | sendRedirect() (重定向) | forward() (请求转发) |
---|---|---|
请求次数 | 两次请求 | 一次请求 |
地址栏是否改变 | 是 | 否 |
数据共享 | 不能共享 request 作用域数据 | 可以共享 request 数据 |
是否能跳转到外部 | 可以(可以跳转到其他网站) | 不能(仅限本 Web 应用) |
性能 | 相对较低(多一次 HTTP 请求) | 较高(在服务器内部处理) |
适用场景 | 跳转到外部站点、不同 Web 应用 | 访问同一应用内的页面 |
4. 何时使用?
-
使用
sendRedirect()
:-
需要跳转到外部站点(如
response.sendRedirect("https://www.google.com")
)。 -
需要让用户看到新 URL(如 OAuth 登录跳转)。
-
不能共享
request
数据,或希望开始一个新的请求时。
-
-
使用
forward()
:-
需要在同一个 Web 应用内跳转,并且共享
request
数据(如request.setAttribute()
)。 -
服务器端控制跳转,并且不希望 URL 变化时。
-
适用于 MVC 模式中从 Servlet 跳转到 JSP 处理页面。
-
5. 代码示例:对比两者
@WebServlet("/redirectOrForward")
public class RedirectOrForwardServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String type = request.getParameter("type");
if ("redirect".equals(type)) {
response.sendRedirect("https://www.baidu.com"); // 重定向
} else if ("forward".equals(type)) {
RequestDispatcher dispatcher = request.getRequestDispatcher("newPage.jsp");
dispatcher.forward(request, response); // 请求转发
}
}
}
测试
-
访问:
http://localhost:8080/redirectOrForward?type=redirect
→ 跳转到 Baidu -
访问:
http://localhost:8080/redirectOrForward?type=forward
→ 服务器内部转发到newPage.jsp
6. 结论
-
sendRedirect()
适用于外部跳转,是两次请求,地址栏变化,不能共享request
数据。 -
forward()
适用于内部跳转,是一次请求,地址栏不变,可以共享request
数据。 -
一般情况下,性能要求高的跳转可选
forward()
,跳转外部或不同应用时选sendRedirect()
。
🚀 面试技巧:如果面试官问你区别,一定要结合 HTTP 请求次数、地址栏变化、数据共享等角度回答,并尽量提供代码示例!
如果觉得这篇博客对你有帮助,记得点赞 ⭐、收藏 📌、关注 🚀!