来自 jsp:include 的 response.sendRedirect() 被忽略?
Posted
技术标签:
【中文标题】来自 jsp:include 的 response.sendRedirect() 被忽略?【英文标题】:response.sendRedirect() from jsp:include being ignored? 【发布时间】:2011-07-09 22:49:52 【问题描述】:我有一个 jsp 文件,其中包含另一个 jsp 文件来检查一些值等:
<jsp:include page="setup.jsp" />
在 setup.jsp 中,我有一些条件代码,用于确定是否在会话中设置了一些需要的值,如果没有,则将它们重定向到不同的页面。或者至少应该如此,但重定向似乎被忽略了。
System.err.println("Redirecting!");
response.sendRedirect("http://www.google.com");
return;
我看到“重定向!”登录到控制台,但页面继续并正常呈现。我让 curl 为我转储了标头,发现响应是 HTTP/1.1 200 OK
,所以它肯定没有发送 302 重定向。
知道问题出在哪里以及如何解决这个问题吗?
编辑:我已确认我的回复尚未提交。 response.isCommitted()
返回false
表示状态码和标头尚未发送。
编辑 2:我尝试在许多其他地方调用 response.sendRedirect()
并发现我可以在 . JSP 内部的重定向似乎被忽略了,如果我尝试在 jsp 之后立即重定向,那么我会得到一个非法状态异常,因为响应已经提交。
【问题讨论】:
有可能部分响应已经发送到客户端并且重定向被忽略。重定向应该(几乎)首先被解析。 我必须把它放在一个更大的网络应用程序结构中,所以当涉及到何时何地可以放置代码以进行重定向时,我的双手被束缚了。当我尝试进行重定向时,有没有一种方法可以测试响应是否已经将内容传递回浏览器?当我沉浸在 jsp:includes 中时,您对如何启动某种重定向有什么建议吗? 我在调用重定向的位置添加了一个简单的 out.println() 消息,并且该输出出现在响应的任何其他输出之前。那我不应该被允许重定向吗? 好的,我发现 response.isCommitted() 是一种确定标头是否已写入的方法。响应尚未提交,因此它仍应对重定向开放。 【参考方案1】:<jsp:include>
在幕后使用RequestDispatcher#include()
。单击链接以查看 javadoc。这是相关性的摘录(强调我的):
...
ServletResponse 对象的路径元素和参数与调用者的保持不变。 包含的servlet不能改变响应状态码或设置headers;任何进行更改的尝试都会被忽略。
...
HttpServletResponse#sendRedirect()
基本上将 HTTP 响应状态设置为 302
,并将 HTTP Location
标头设置为目标 URL。因此它被完全忽略了。
更深层次的问题是您滥用 JSP 作为页面控制器/过滤器。您实际上应该为此使用普通的 servlet 或 filter 类,它远在 JSP 之前运行。
【讨论】:
我完全同意这种滥用,不幸的是,我需要适应一些非常严格的界限。谢谢上面的sn-p文档,我不知道。【参考方案2】:重定向标题(我相信)需要位于页面顶部。查看 html 规范以供参考。
您是否尝试将其放在页面的最顶部?一个代码示例将帮助我们调试...
【讨论】:
不幸的是,由于我的客户的隐私问题,我无法提供太多的代码 sn-ps 方式。这是一个相当复杂的站点,包含多个级别的 jsp:includes 等。 我已验证在我尝试重定向时未发送任何状态代码或其他标头,因此它实际上位于“页面顶部”。以上是关于来自 jsp:include 的 response.sendRedirect() 被忽略?的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 Typescript 编译错误 ts2345“类型 'Response' 丢失......来自'Response'类型:重定向、预告片、formData!”
来自 WebApi2 response.data 的 Angular ng-repeat 刷新