RequestDispatcher 包含脚本时无法重定向

Cannot redirect when the script is include by RequestDispatcher

我在 jsp 中遇到重定向问题,该页面保持不变,不会引发任何错误。

当我直接在我的 login.jsp 中编写脚本时,我能够进行重定向,例如

<%
String redirectURL = "/client/index.jsp";
response.sendRedirect(redirectURL);
%>
<t:login title="Client Login">
..........
</t:login>

但是我将文件分成三个并包含它时,我无法执行重定向。下面是我的实现。

login.jsp

<%@include file="/include/checkhandler.jsp"%>

checkhandler.jsp - 这是一个脚本,它将检查处理程序文件夹中的文件并在文件存在时包含它。

......
request.getRequestDispatcher(handler).include(request, response);
......

login_handler.jsp 这是调度程序将包含的文件

String redirectURL = "/client/index.jsp";
response.sendRedirect(redirectURL);
out.println("hello world");

我执行这个脚本后,hello world 显示了,但它仍然停留在同一页面,没有任何错误。

您需要改用 RequestDispatcher#forward()。将 checkhandler.jsp 更改为

request.getRequestDispatcher(handler).forward(request, response);

A server-side include 被禁止更改响应状态代码,当您使用 sendRedirect() 时会发生这种情况。容器会简单地忽略任何此类尝试。

来自 RequestDispatcher#include() 文档:

The ServletResponse object has its path elements and parameters remain unchanged from the caller's. The included servlet cannot change the response status code or set headers; any attempt to make a change is ignored.

此限制是设计使然。该规范将 Web 组件视为 guest 即它 无法引导流程 并且任何此类尝试都将被正确地 忽略而不是抛出异常 可能允许包含您可能拥有的任何 servlet。

只有托管 Web 组件(执行包含的组件)才能完全控制流程以及发送给客户端的响应 headers。

你的代码中有这个

out.println("hello world");
String redirectURL = "/client/index.jsp";
response.sendRedirect(redirectURL);

这将不起作用,因为您不能在写入响应流后重定向。重定向在响应 header 中发送。响应 body 不应包含任何 html.