在 Web 开发领域,术语“重定向”是指向客户端发送一个空的 HTTP 响应,其中仅包含一个Location
标头包含客户端必须向其发送全新 GET 请求的新 URL。所以基本上:
- 客户端发送 HTTP 请求到
some.jsp
.
- 服务器发回 HTTP 响应
Location: other.jsp
header
- 客户端发送 HTTP 请求到
other.jsp
(这会反映在浏览器地址栏中!)
- 服务器发送回 HTTP 响应,内容为
other.jsp
.
您可以使用网络浏览器的内置/插件开发工具集来跟踪它。在 Chrome/IE9/Firebug 中按 F12 并检查“网络”部分即可看到。
上面的内容正是通过以下方式实现的sendRedirect("other.jsp")
. The RequestDispatcher#forward()
不发送重定向。相反,它使用目标页面的内容作为 HTTP 响应。
- 客户端发送 HTTP 请求到
some.jsp
.
- 服务器发送回 HTTP 响应,内容为
other.jsp
.
然而,由于原始 HTTP 请求是some.jsp
,浏览器地址栏中的URL保持不变。此外,在后面的控制器中设置的任何请求属性some.jsp
将在other.jsp
。这在重定向期间不会发生,因为您基本上是在强制客户端创建一个newHTTP 请求开启other.jsp
,特此丢弃原来的请求some.jsp
包括它的所有属性。
The RequestDispatcher
在 MVC 范例中和/或当您想要隐藏 JSP 以防止直接访问时非常有用。您可以将 JSP 放入/WEB-INF
文件夹并使用Servlet
它控制、预处理和后处理请求。 JSP 位于/WEB-INF
文件夹不能直接通过 URL 访问,但Servlet
可以使用访问它们RequestDispatcher#forward()
.
例如,您可以有一个 JSP 文件/WEB-INF/login.jsp
and a LoginServlet
它被映射到url-pattern
of /login
。当你调用http://example.com/context/login
,然后 servlet 的doGet()
将被调用。你可以在那里做任何预处理的事情,最后forward请求如:
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
当您提交表单时,您通常想要使用POST
:
<form action="login" method="post">
这样servlet的doPost()
将被调用,您可以在其中执行任何后处理操作(例如验证、业务逻辑、登录用户等)。
如果有任何错误,那么您通常需要forward请求返回同一页面并在输入字段旁边显示错误等。您可以使用RequestDispatcher
为了这。
If a POST
成功后,您通常想要redirect请求,以便当用户刷新请求时(例如按 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.
}
A redirect从而指示客户端触发一个新的GET
对给定 URL 的请求。刷新请求只会刷新重定向的请求,而不刷新初始请求。这将避免“双重提交”以及混乱和不良的用户体验。这也称为POST-Redirect-GET pattern.
也可以看看:
- Servlet 如何工作?实例化、会话、共享变量和多线程
- Servlet 中的 doGet 和 doPost
- 如何在JSP中执行验证并以相同的形式显示错误消息?
- HttpServletResponse sendRedirect 永久