forward()
和sendRedirect()
的概念上有何区别?
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
当您提交表单时,通常要使用 POST
方法:
<form action="login" method="post">
这样,servlet的doPost()
方法将被调用,您可以在其中进行任何后处理工作(例如验证、业务逻辑、用户登录等)。
如果有任何错误,通常希望将请求转发回同一页,并在输入字段旁边显示错误。您可以使用RequestDispatcher
来实现这一点。
如果POST
成功,通常希望重定向请求,以便用户刷新请求时不会重新提交请求(例如按F5键或在历史记录中导航)。
User user = userDAO.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user); // Login user.
response.sendRedirect("home"); // Redirects to http://example.com/context/home after succesful login.
} else {
request.setAttribute("error", "Unknown login, please try again."); // Set error.
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to same page so that you can display error.
}
重定向指示客户端在给定的URL上发起新的GET
请求。刷新请求将仅刷新经过重定向的请求,而不是初始请求。这将避免“双重提交”、混淆和糟糕的用户体验。这也称为POST-Redirect-GET
模式。
当我们使用 forward
方法时,请求会被传输到同一服务器内的另一个资源以进行进一步处理。
在使用 forward
的情况下,Web 容器会在内部处理所有的处理工作,客户端或浏览器不会参与其中。
当在 requestDispatcher
对象上调用 forward
时,我们传递了请求和响应对象,因此我们旧的请求对象存在于将要处理我们的请求的新资源上。
从视觉上看,我们无法看到转发地址,它是透明的。
使用 forward()
方法比使用 sendRedirect
更快。
当我们使用 forward 进行重定向时,并且我们想在新的资源中使用相同的数据,我们可以使用 request.setAttribute()
,因为我们有一个可用的请求对象。
在使用 sendRedirect
的情况下,请求会被传输到另一个资源、不同的域或不同的服务器以进行进一步处理。
当您使用 sendRedirect
时,容器会将请求传输到客户端或浏览器,因此在 sendRedirect
方法中给出的 URL 会作为新请求对客户端可见。
在使用 sendRedirect
调用时,旧的请求和响应对象会丢失,因为它被浏览器视为新请求。
在地址栏中,我们能够看到新的重定向地址。这不是透明的。
sendRedirect
更慢,因为需要额外的一次往返,因为创建了一个全新的请求,并且旧的请求对象已丢失。需要两个浏览器请求。
但是,在 sendRedirect
中,如果我们想要为新资源使用相同的数据,我们必须在会话中存储数据或将其随 URL 一起传递。
这取决于使用场景,哪种方法更有用。
如果您希望控制转移到新服务器或上下文,并且它被视为完全新的任务,则使用 sendRedirect
。
通常,如果操作可以在 Web 页面重新加载时安全地重复执行并且不会影响结果,则应使用 forward。
RequestDispatcher
接口允许您在服务器端执行转发/包含操作,而 sendRedirect()
则执行客户端重定向。在客户端重定向中,服务器将发送 HTTP 状态码为 302
(临时重定向),这会导致 web 浏览器为重新定位的位置发出全新的 HTTP GET
请求以获取内容。相反,在使用RequestDispatcher
接口时,对于新资源的包含/转发完全在服务器端处理。
SendRedirect()
用于在服务器之间搜索内容,由于需要向浏览器发送内容的URL并通知浏览器,所以速度较慢。然后浏览器会为同一服务器或另一个服务器内的内容创建一个新请求。
RquestDispatcher
是用于在服务器内搜索内容的,它是服务器端过程,并且与SendRedirect()
方法相比更快。但问题在于它不会告知浏览器它正在搜索所需日期或内容的服务器,在URL标签中也不会要求浏览器更改URL。因此它给用户带来了一些不便。
从技术上讲,重定向应该用于需要将控制权转移到不同域或实现任务分离的情况。
例如,在支付应用程序中,我们首先执行PaymentProcess,然后重定向到displayPaymentInfo。如果客户端刷新浏览器,只会重新执行displayPaymentInfo,而PaymentProcess不会被重复执行。但是,如果在此场景中使用forward,则PaymentProcess和displayPaymentInfo都将按顺序重新执行,这可能导致数据不一致。
对于其他场景,forward的效率更高,因为它比sendRedirect更快。
仅仅区别于Forward(ServletRequest request, ServletResponse response)
和sendRedirect(String url)
方法是:
forward():
forward()
方法在服务器端执行。forward()
方法比sendRedirect()
方法更快。RequestDispatcher
接口中声明。sendRedirect():
请求分派程序是一种接口,用于将来自Web资源的请求或响应分派到另一个Web资源。它主要包含两种方法。
request.forward(req, res)
:此方法用于将请求从一个Web资源转发到另一个资源,例如从一个servlet到另一个servlet或从一个Web应用程序到另一个Web应用程序。
response.include(req, res)
:此方法用于将一个servlet的响应包含在另一个servlet中
注意: 使用请求分派器我们可以在同一个服务器内转发或包含请求或响应。
request.sendRedirect()
: 通过使用此功能,我们可以在不同的服务器之间转发或包含请求或响应。在此过程中,客户端在重定向页面时会得到提醒,但在上述过程中,客户端将不会得到提醒。