Answers:
requestDispatcher-forward()方法
当我们使用该
forward
方法时,请求将被转移到同一服务器内的另一个资源以进行进一步处理。在情况下
forward
,Web容器在内部处理所有处理,并且不涉及客户端或浏览器。在对象
forward
上调用when时requestDispatcher
,我们传递了请求和响应对象,因此旧的请求对象存在于将处理请求的新资源上。从视觉上看,我们看不到转发的地址,它是透明的。
使用该
forward()
方法比sendRedirect
。当我们使用正向重定向时,如果我们想在新资源中使用相同的数据,则可以使用
request.setAttribute()
请求对象,因为我们可以使用它。发送重定向
在的情况下
sendRedirect
,请求将转移到另一个资源,另一个域或另一个服务器以进行进一步处理。当您使用时
sendRedirect
,容器会将请求传输到客户端或浏览器,因此,在sendRedirect
方法内部给出的URL 作为对客户端的新请求可见。如果发生
sendRedirect
调用,则旧的请求和响应对象将丢失,因为浏览器将其视为新请求。在地址栏中,我们可以看到新的重定向地址。这不是透明的。
sendRedirect
速度较慢,因为需要进行一次额外的往返行程,因为会创建一个全新的请求,而旧的请求对象将丢失。需要两个浏览器请求。但是在中
sendRedirect
,如果我们想为新资源使用相同的数据,则必须将数据存储在会话中或与URL一起传递。哪个好?
它取决于哪种方法更有用的方案。
如果您希望将控制权转移到新服务器或上下文中,并且将其视为全新任务,那么我们去寻求
sendRedirect
。通常,如果在浏览器重新加载网页后可以安全地重复该操作并且不会影响结果,则应使用转发。
在Web开发世界中,术语“重定向”是向客户端发送一个空的HTTP响应,该响应仅Location
包含一个标头,该标头包含客户端必须向其发送全新的GET请求的新URL。所以基本上:
some.jsp
。Location: other.jsp
标头other.jsp
(这将反映在浏览器地址栏中!)other.jsp
。您可以使用网络浏览器的内置/附加开发人员工具集对其进行跟踪。在Chrome / IE9 / Firebug中按F12,然后检查“网络”部分以查看它。
正是通过sendRedirect("other.jsp")
。在RequestDispatcher#forward()
不发送重定向。相反,它将目标页面的内容用作HTTP响应。
some.jsp
。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.jsp
和LoginServlet
其上映射url-pattern
的/login
。当您调用时http://example.com/context/login
,doGet()
将调用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
模式。
该RequestDispatcher
界面允许您执行服务器端转发/包含,而sendRedirect()
客户端重定向。在客户端重定向中,服务器将发回HTTP状态代码302
(临时重定向),这将导致Web浏览器对GET
重定向位置的内容发出全新的HTTP 请求。相反,使用RequestDispatcher
接口时,包含/转发到新资源的操作完全在服务器端进行。
forward
,而不是重定向。
forward()和sendRedirect()方法之间的主要区别是,在forward()情况下,重定向发生在服务器端,对客户端不可见,但是在sendRedirect()情况下,重定向发生在客户端,并且可见给客户。
从技术上讲,如果我们需要将控制权转移到其他域或实现任务分离,则应使用重定向。
例如,在付款应用程序中,我们首先执行PaymentProcess,然后重定向到displayPaymentInfo。如果客户端刷新浏览器,则仅displayPaymentInfo会再次执行,并且PaymentProcess将不会重复。但是,如果在这种情况下使用正向,则PaymentProcess和displayPaymentInfo都会顺序执行,这可能会导致数据混乱。
在其他情况下,因为转发比sendRedirect更快,所以转发的使用效率很高。
请求分派器是一个接口,用于将请求或响应从Web资源分发到另一个Web资源。它主要包含两种方法。
request.forward(req,res)
:使用此方法将请求从一个Web资源转发到另一资源。即从一个servlet到另一个servlet或从一个Web应用程序到另一个Web应用程序。
response.include(req,res)
:使用此方法包括一个servlet对另一个servlet的响应
注意:通过使用Request Dispatcher,我们可以将请求或响应转发或包含在同一服务器中。
request.sendRedirect()
:通过使用此功能,我们可以跨不同服务器转发或包括请求或响应。在这种情况下,客户端在重定向页面时会得到提示,但是在上述过程中,客户端将不会获得提示
Forward(ServletRequest request, ServletResponse response)
和之间的简单区别sendRedirect(String url)
是
前锋():
forward()
方法在服务器端执行。forward ()
方法由Servlet容器提供,因此它不依赖于客户端的请求协议。forward()
方法比sendRedirect()
方法快。RequestDispatcher
接口中声明。sendRedirect():
response.sendRedirect("..")
到网站的index.jsp页面。但这会漏掉css文件和jsp页面中的一些文本,从而导致页面的部分加载。但是,当我将网站的欢迎页面设置为index.jsp时,一切正常,页面加载完成。重定向有什么问题?