RequestDispatcher.forward()与HttpServletResponse.sendRedirect()


Answers:


106

requestDispatcher-forward()方法

  1. 当我们使用该forward方法时,请求将被转移到同一服务器内的另一个资源以进行进一步处理。

  2. 在情况下forward,Web容器在内部处理所有处理,并且不涉及客户端或浏览器。

  3. 在对象forward上调用when时requestDispatcher,我们传递了请求和响应对象,因此旧的请求对象存在于将处理请求的新资源上。

  4. 从视觉上看,我们看不到转发的地址,它是透明的。

  5. 使用该forward()方法比sendRedirect

  6. 当我们使用正向重定向时,如果我们想在新资源中使用相同的数据,则可以使用request.setAttribute()请求对象,因为我们可以使用它。

发送重定向

  1. 在的情况下sendRedirect,请求将转移到另一个资源,另一个域或另一个服务器以进行进一步处理。

  2. 当您使用时sendRedirect,容器会将请求传输到客户端或浏览器,因此,在sendRedirect方法内部给出的URL 作为对客户端的新请求可见。

  3. 如果发生sendRedirect调用,则旧的请求和响应对象将丢失,因为浏览器将其视为新请求。

  4. 在地址栏中,我们可以看到新的重定向地址。这不是透明的。

  5. sendRedirect速度较慢,因为需要进行一次额外的往返行程,因为会创建一个全新的请求,而旧的请求对象将丢失。需要两个浏览器请求。

  6. 但是在中sendRedirect,如果我们想为新资源使用相同的数据,则必须将数据存储在会话中或与URL一起传递。

哪个好?

它取决于哪种方法更有用的方案。

如果您希望将控制权转移到新服务器或上下文中,并且将其视为全新任务,那么我们去寻求sendRedirect。通常,如果在浏览器重新加载网页后可以安全地重复该操作并且不会影响结果,则应使用转发。

资源


161

在Web开发世界中,术语“重定向”是向客户端发送一个空的HTTP响应,该响应仅Location包含一个标头,该标头包含客户端必须向其发送全新的GET请求的新URL。所以基本上:

  • 客户端向发送HTTP请求some.jsp
  • 服务器将HTTP响应发送回Location: other.jsp标头
  • 客户端向发送HTTP请求other.jsp(这将反映在浏览器地址栏中!)
  • 服务器发回HTTP响应,内容为other.jsp

您可以使用网络浏览器的内置/附加开发人员工具集对其进行跟踪。在Chrome / IE9 / Firebug中按F12,然后检查“网络”部分以查看它。

正是通过sendRedirect("other.jsp")。在RequestDispatcher#forward()不发送重定向。相反,它将目标页面的内容用作HTTP响应。

  • 客户端向发送HTTP请求some.jsp
  • 服务器发回HTTP响应,内容为other.jsp

但是,由于原始HTTP请求是some.jsp,浏览器地址栏中的URL保持不变。另外,后面的控制器中设置的所有请求属性some.jsp都将在中提供other.jsp。在重定向过程中不会发生这种情况,因为您基本上是在强迫客户端在上创建一个新的 HTTP请求other.jsp,从而丢弃原始请求(some.jsp包括所有属性)。


RequestDispatcher在MVC范例中和/或要从直接访问中隐藏JSP时,它非常有用。您可以将JSP放在/WEB-INF文件夹中,并使用Servlet来控制,预处理和后处理请求。/WEB-INF不能通过URL直接访问该文件夹中的JSP ,但是Servlet可以使用来访问它们RequestDispatcher#forward()

例如,你可以在一个JSP文件/WEB-INF/login.jspLoginServlet其上映射url-pattern/login。当您调用时http://example.com/context/logindoGet()将调用servlet 。您可以在其中进行任何预处理,最后转发请求,例如:

request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);

提交表单时,通常要使用POST

<form action="login" method="post">

这样,doPost()将调用servlet,并且您可以在其中进行任何后期处理(例如,验证,业务逻辑,登录用户等)。

如果有任何错误,则通常需要将请求转发回同一页面,并在输入字段旁边显示错误,依此类推。您可以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.
}

一个重定向从而指示客户端触发一个新的GET给定的URL请求。然后刷新请求将仅刷新重定向的请求,而不刷新初始请求。这将避免“两次提交”,混乱和不良的用户体验。这也称为POST-Redirect-GET模式

也可以看看:


当我从servlet重定向到jsp页面时,jsp页面被部分加载,如stackoverflow.com/questions/12337624/…所示。我希望在有人点击foo.com时运行的第一件事就是该servlet。我从servlet response.sendRedirect("..")到网站的index.jsp页面。但这会漏掉css文件和jsp页面中的一些文本,从而导致页面的部分加载。但是,当我将网站的欢迎页面设置为index.jsp时,一切正常,页面加载完成。重定向有什么问题?
saplingPro 2012年

20

RequestDispatcher界面允许您执行服务器端转发/包含,而sendRedirect()客户端重定向。在客户端重定向中,服务器将发回HTTP状态代码302(临时重定向),这将导致Web浏览器对GET重定向位置的内容发出全新的HTTP 请求。相反,使用RequestDispatcher接口时,包含/转发到新资源的操作完全在服务器端进行。


而后者实际上是forward,而不是重定向。
Adeel Ansari 2010年


4

这些方法中的任何一种都可能是“更好的”,即更适合,具体取决于您要执行的操作。

如果您从其他页面获取数据而无需往返浏览器,则服务器端重定向会更快。但是在浏览器中看到的URL仍然是原始地址,因此您在此处创建了一些不一致之处。

客户端重定向的功能更广泛,因为它可以将您发送到完全不同的服务器,或者更改协议(例如,从HTTP更改为HTTPS),或同时执行两者。并且浏览器知道新的URL。但是,这需要在服务器和客户端之间进行额外的往返操作。


2
网上没有足够提及此段:“或更改协议(例如,从HTTP更改为HTTPS),或同时
更改

3

SendRedirect()将在服务器之间搜索内容。这很慢,因为它必须通过发送内容的URL来使浏览器亲密。然后浏览器将在同一服务器或另一服务器中为内容创建新请求。

RquestDispatcher是用于搜索我认为的服务器内的内容。它是服务器端的过程,与该SendRedirect()方法相比,速度更快。但事实是,它不会使浏览器在所需的日期或内容所在的服务器上相互联系,也不会要求浏览器更改“ URL”选项卡中的URL。因此给用户带来的不便很少。


1

从技术上讲,如果我们需要将控制权转移到其他域或实现任务分离,则应使用重定向。

例如,在付款应用程序中,我们首先执行PaymentProcess,然后重定向到displayPaymentInfo。如果客户端刷新浏览器,则仅displayPaymentInfo会再次执行,并且PaymentProcess将不会重复。但是,如果在这种情况下使用正向,则PaymentProcess和displayPaymentInfo都会顺序执行,这可能会导致数据混乱。

在其他情况下,因为转发比sendRedirect更快,所以转发的使用效率很高。


0

请求分派器是一个接口,用于将请求或响应从Web资源分发到另一个Web资源。它主要包含两种方法。

  1. request.forward(req,res):使用此方法将请求从一个Web资源转发到另一资源。即从一个servlet到另一个servlet或从一个Web应用程序到另一个Web应用程序。

  2. response.include(req,res):使用此方法包括一个servlet对另一个servlet的响应

注意:通过使用Request Dispatcher,我们可以将请求或响应转发或包含在同一服务器中。

request.sendRedirect():通过使用此功能,我们可以跨不同服务器转发或包括请求或响应。在这种情况下,客户端在重定向页面时会得到提示,但是在上述过程中,客户端将不会获得提示


-1

Forward(ServletRequest request, ServletResponse response)和之间的简单区别sendRedirect(String url)

前锋():

  1. forward()方法在服务器端执行。
  2. 该请求将传输到同一服务器内的其他资源。
  3. 由于该forward ()方法由Servlet容器提供,因此它不依赖于客户端的请求协议。
  4. 该请求由目标资源共享。
  5. 此方法仅消耗一个调用。
  6. 可以在服务器内使用。
  7. 我们看不到转发的消息,它是透明的。
  8. forward()方法比sendRedirect()方法快。
  9. RequestDispatcher接口中声明。

sendRedirect():

  1. sendRedirect()方法在客户端执行。
  2. 该请求将转移到其他资源到不同的服务器。
  3. HTTP下提供了sendRedirect()方法,因此它只能与HTTP客户端一起使用。
  4. 为目标资源创建了新请求。
  5. 使用了两个请求和响应调用。
  6. 它可以在服务器内部和外部使用。
  7. 我们可以看到重定向的地址,它不是透明的。
  8. sendRedirect()方法比较慢,因为在创建新请求时,旧的请求对象会丢失。
  9. 它在HttpServletResponse中声明。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.