RequestDispatcher.forward()vs HttpServletResponse.sendRedirect()
forward()
和sendRedirect()
之间的概念区别是什么?
requestDispatcher - forward()方法
当我们使用forward方法时,请求被转移到同一个服务器中的其他资源中作进一步处理。
在转发的情况下,Web容器处理所有内部进程,并且不涉及客户端或浏览器。
当在requestdispatcher对象上调用forward时,我们传递请求和响应对象,以便我们的旧请求对象出现在正在处理我们的请求的新资源上。
在视觉上,我们无法看到转发的地址,它是透明的。
使用forward()方法比发送重定向要快。
当我们使用forward进行重定向并且我们想要在新资源中使用相同的数据时,我们可以使用request.setAttribute(),因为我们有请求对象可用。
的sendRedirect
在sendRedirect的情况下,将请求转移到另一个资源到不同的域或不同的服务器以供进一步处理。
当您使用sendRedirect时,容器会将请求传输到客户端或浏览器,以便在sendRedirect方法中给出的URL作为对客户端的新请求可见。
在sendRedirect调用的情况下,旧的请求和响应对象由于被浏览器视为新请求而丢失。
在地址栏中,我们可以看到新的重定向地址。 它不透明。
sendRedirect比较慢,因为需要额外的往返行程,因为全新的请求被创建并且旧的请求对象丢失。 需要两个浏览器请求。
但在sendRedirect中,如果我们想要使用,我们必须将数据存储在会话中或与URL一起传递。
哪一个很好?
它取决于哪种方法更有用的场景。
如果你想控制转移到新的服务器或上下文,它被视为全新的任务,那么我们去发送重定向。 一般来说,如果在浏览器重新加载网页时可以安全地重复该操作,则不会影响结果,所以应该使用转发。
资源
首先,术语“重定向”在Web开发世界中是向客户端发送空HTTP响应的动作,其中仅具有Location
头,其中客户端必须发送新的GET请求的新URL。 所以基本上:
some.jsp
发送HTTP请求。 Location: other.jsp
标头返回HTTP响应 other.jsp
发送HTTP请求(这反映在浏览器地址栏中!) other.jsp
内容的HTTP响应。 您可以使用webbrowser的内建/插件开发人员工具集进行跟踪。 按下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
来控制,预处理和后处理请求。 /WEB-INF
文件夹中的JSP不能通过URL直接访问,但Servlet
可以使用RequestDispatcher#forward()
访问它们。
例如,您可以在/WEB-INF/login.jsp
拥有一个JSP文件,并在/login
的url-pattern
上映射一个LoginServlet
。 当你调用http://example.com/context/login
,servlet的doGet()
将被调用。 你可以在那里做任何预处理的东西,并最终转发请求,如:
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
模式。
RequestDispatcher
接口允许你做一个服务器端转发/包含,而sendRedirect()
做一个客户端重定向。 在客户端重定向中,服务器将发回302
状态码(临时重定向),这将导致Web浏览器为重定向位置的内容发出全新的HTTP GET
请求。 相比之下,使用RequestDispatcher
接口时,包含/转发到新资源完全在服务器端处理。
上一篇: RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()