forward()
和sendRedirect()
之间的概念差异是什么?
答案 0 :(得分:156)
在Web开发世界中,术语“重定向”是向客户端发送空HTTP响应的行为,其中只有Location
标头,其中包含客户端必须向其发送全新GET请求的新URL 。所以基本上:
some.jsp
发送HTTP请求。Location: other.jsp
标题other.jsp
发送HTTP请求(这反映在浏览器地址栏中!)other.jsp
的HTTP响应。您可以使用网络浏览器的内置/插件开发人员工具集进行跟踪。在Chrome / IE9 / Firebug中按F12,然后选中“网络”部分进行查看。
上述内容完全由sendRedirect("other.jsp")
实现。 RequestDispatcher#forward()
不会发送重定向。相反,它使用目标页面的内容作为HTTP响应。
some.jsp
发送HTTP请求。other.jsp
的HTTP响应。但是,由于原始HTTP请求是some.jsp
,因此浏览器地址栏中的URL保持不变。
RequestDispatcher
在MVC范例中非常有用,并且/或者当您想要隐藏JSP直接访问时。您可以将JSP放在/WEB-INF
文件夹中,并使用Servlet
来控制,预处理和后处理请求。 URL无法直接访问/WEB-INF
文件夹中的JSP,但Servlet
可以使用RequestDispatcher#forward()
访问它们。
例如,您可以在/WEB-INF/login.jsp
中创建一个JSP文件,并在LoginServlet
url-pattern
上映射/login
。当您调用http://example.com/context/login
时,将调用servlet的doGet()
。你可以在那里做任何 pre 处理的东西,最后转发请求,如:
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
提交表单时,通常需要使用POST
:
<form action="login" method="post">
这样servlet的doPost()
将被调用,你可以在那里做任何 post 处理(例如验证,业务逻辑,登录用户等)。
如果有任何错误,那么您通常希望将转发请求返回到同一页面,并在输入字段旁边显示错误,依此类推。您可以使用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
pattern。
答案 1 :(得分:93)
requestDispatcher - forward()方法
当我们使用
forward
方法时,请求会转移到同一服务器中的另一个资源,以便进一步处理。对于
forward
,Web容器在内部处理所有处理,并且不涉及客户端或浏览器。在
forward
对象上调用requestDispatcher
时,我们传递请求和响应对象,因此我们的旧请求对象出现在将要处理我们请求的新资源上。从视觉上看,我们无法看到转发的地址,它是透明的。
使用
forward()
方法比sendRedirect
更快。- 醇>
当我们使用转发重定向时,我们希望在新资源中使用相同的数据时,我们可以使用
request.setAttribute()
,因为我们有一个可用的请求对象。的sendRedirect
如果是
sendRedirect
,请求会转移到其他资源,转移到其他域或转移到 不同的服务器进行进一步处理。当您使用
sendRedirect
时,容器会将请求传输到客户端或浏览器,因此sendRedirect
方法中给出的URL作为对客户端的新请求可见。如果
sendRedirect
调用,旧请求和响应对象将丢失,因为它被浏览器视为新请求。在地址栏中,我们可以看到新的重定向地址。它不透明。
sendRedirect
速度较慢,因为需要额外的往返行程,因为会创建一个全新的请求并丢失旧的请求对象。需要两个浏览器请求。- 醇>
但在
sendRedirect
中,如果我们想要使用,我们必须将数据存储在会话中或与URL一起传递。哪一个好?
它取决于哪种方法更有用的场景。
如果您希望控件转移到新服务器或上下文,并将其视为全新任务,那么我们转到
sendRedirect
。 通常,如果在浏览器重新加载网页时可以安全地重复操作,并且不会影响结果,则应使用转发。
答案 2 :(得分:19)
RequestDispatcher
接口允许您执行服务器端转发/包含,而sendRedirect()
执行客户端重定向。在客户端重定向中,服务器将发回HTTP状态代码302
(临时重定向),这会导致Web浏览器对重定向位置的内容发出全新的HTTP GET
请求。相反,当使用RequestDispatcher
接口时,新资源的包含/转发完全在服务器端处理。
答案 3 :(得分:3)
这些方法中的任何一种都可能“更好”,即更合适,这取决于你想做什么。
如果您从不同的页面获取数据而不进行浏览器往返,则服务器端重定向会更快。但是在浏览器中看到的URL仍然是原始地址,因此您在那里创建了一点不一致。
客户端重定向功能更加通用,因为它可以将您发送到完全不同的服务器,或更改协议(例如,从HTTP到HTTPS),或两者兼而有之。浏览器知道新的URL。但它需要在服务器和客户端之间进行额外的反复。
答案 4 :(得分:3)
SendRedirect()
将搜索服务器之间的内容。它很慢,因为它必须通过发送内容的URL来接近浏览器。然后,浏览器将在同一服务器或另一台服务器内创建新内容请求。
RquestDispatcher
用于搜索我认为的服务器内的内容。它是服务器端进程,与SendRedirect()
方法相比速度更快。但问题是,它不会在浏览器中查询所搜索的服务器所需的日期或内容,也不会要求浏览器更改URL选项卡中的URL。所以它不会给用户带来任何不便。
答案 5 :(得分:2)
forward()和sendRedirect()方法之间的主要区别在于,对于forward(),发生重定向 在服务器端,对客户端不可见,但是在 sendRedirect(),重定向发生在客户端,并且对 客户。
答案 6 :(得分:1)
如果我们需要将控制转移到不同的域或实现任务分离,则应使用技术上的重定向。
例如在支付应用程序中 我们首先执行PaymentProcess,然后重定向到displayPaymentInfo。如果客户端刷新浏览器,则只会再次执行displayPaymentInfo,并且不会重复PaymentProcess。但是如果我们在这种情况下使用forward,则PaymentProcess和displayPaymentInfo将按顺序重新执行,这可能会导致数据不存在。
对于其他方案,forward可以高效使用,因为它比sendRedirect
更快答案 7 :(得分:0)
Request Dispatcher是一个接口,用于将请求或响应从Web资源分派到另一个Web资源。它主要包含两种方法。
request.forward(req,res)
:此方法用于将请求从一个Web资源转发到另一个资源。即从一个servlet到另一个servlet,或从一个Web应用程序到另一个Web应用程序。
response.include(req,res)
:此方法用于包括一个servlet对另一个servlet的响应
注意:通过使用Request Dispatcher,我们可以在同一服务器中转发或包含请求。
request.sendRedirect()
:通过使用此功能,我们可以跨不同服务器转发或包含请求。在此,客户端在重定向页面时获得了一个暗示,但在上述过程中,客户端将无法获取信息
答案 8 :(得分:-1)
分派器允许请求数据从一个servlet传输到另一servlet。请求分派器的替代方法是发送重定向,但是对于每个新请求,发送重定向会在服务器中发生相反的请求分派器时返回到网络。
示例
Java中的Servlet调度程序 让我们通过简单的示例了解请求分配器的概念。考虑一下我们有三个名为servlet1,servlet2和Servlet3的servlet的情况。如果不使用分派器,则每当我们请求servlet1时,服务器就会将控制权传递给servlet1,此后,如果我们请求servlet2,则控制权将从servlet 1传递回服务器并传递给servlet2。在这种情况下,如果服务器位于印度,并且从美国请求servlet,则对于第二个请求,它必须返回到server(India),然后返回到servlet(America)。如果请求和响应之间的流量过大,则此选项不好。解决此问题的方法是调度程序。
Java中的Servlet调度程序 在相同的情况下,如果我们在服务器中使用调度程序,则控制权将从servlet1传递到servlet2,而无需返回服务器且不涉及网络。此概念也称为servlet链接。之所以称为servlet链接,是因为我们正在创建servlet请求的链,从servlet1到servlet2,从Servlet2到Servlet3,服务器将从servlet3获取数据。
数据传递
在servlet链中,不仅传递控制,而且数据也从一个servlet传输到另一个servlet,与发送重定向相比,它的主要优点是。在发送重定向中,每次获取新数据时,每个请求都是新请求。
考虑servlet1有一些应由servlet3执行的请求参数,然后数据可以从servlet1传输到servlet2,然后再从servlet2传输到servlet3,因此这里我们保留了从一个servlet到另一servlet的请求。
请求的寿命非常短,一旦我们获得响应,请求就结束了,但是这里的请求寿命可以从一个servlet保留到另一个。借助于此,我们可以将任务划分为许多servlet。
缺点
大多数时间分配器都是高效的,但在数据量大或我们根本不需要数据的情况下,或者在交易量低的情况下,可以有效地发送重定向工作。
答案 9 :(得分:-1)
Forward(ServletRequest request, ServletResponse response)
和sendRedirect(String url)
之间的简单差异是
forward():
forward()
方法在服务器端执行。forward ()
方法,因此它不依赖于客户端的请求协议。forward()
方法比sendRedirect()
方法快。RequestDispatcher
接口中声明。sendRedirect():