在JSP / Spring中可能导致此IllegalStateException差异的原因是什么?

时间:2010-12-06 02:36:46

标签: spring jsp redirect httprequest forward

我有一个带有c:redirect标记的JSP文件,该标记会沿着用户转发到另一个页面。

<!-- Yes, I know this loop is probably unnecessary, but I'm not fluent in jsp and have determined it is not the problem. :)  -->
<c:if test="${cmd.numberOfResults == 1}"> 
    <c:forEach items="${cmd.matches}" var="someVar">
        <c:redirect url="/loadThatResultInfo.html"/>
    </c:forEach>
</c:if>

命令对象的旧实现需要更新(我进来的地方)。我这样做的方法是创建一个通用的搜索结果&#34;包含该旧对象实例的对象(暂时)。我通过该泛型类中的属性获取该实例,因此我的代码现在是这样的:

<c:if test="${cmd.genericSearchObject.numberOfResults == 1}"> 
    <c:forEach items="${cmd.genericSearchObject.matches}" var="acct">
        <jsp:forward page="/loadThatResultInfo.html"/> <!-- new try! -->
        <c:redirect url="/loadThatResultInfo.html"/>   <!-- old try... -->
        <% response.sendRedirect("/loadThatResultInfo.html"); %> <! new try! -->
    </c:forEach>
</c:if>

这三次尝试中的每一次都会导致某种IllegalStateExceptions。 为什么此更改会导致异常,特别是考虑到涉及的行 - 重定向,而不是更改/绑定的类实例 - 导致问题?

相应地进行了后端更改,引用了我的新内容&#34; generic&#34;用于满足旧功能的类。我知道这很有效,因为除了我所写的内容之外,所有相关的功能都可以使用。

在线研究表明: - 提交完成后我无法重定向/转发。那我怎么能够做到呢? - 尝试刷新已经清除的缓冲区会导致这种情况。改变了什么使它现在被清除而不是旧的(第一次)实施? - 页面缓冲区的大小需要更大。这是我不理解的,并且非常希望stackoverflow社区能够解决这个问题。我可以看到我的新类导致需要更改的大小更改。

-------另一个答案! -------

首先,如标记答案所述,始终设置代码中的情况。但是......如果你陷入困境并且不想这样做,这里有一个快速解决方法:javascript!

<script type="text/javascript">
    location='./yourPageToGoTo.html'
</script>

1 个答案:

答案 0 :(得分:3)

JSP是响应的一部分。您正在尝试更改JSP中的响应目标而不是控制器中的响应目标。如果你在JSP中途执行此操作,则为时已晚,因为HTTP响应标头可能已经发送(然后响应处于已提交状态)。这是一个不归路的点,也是一个改变响应的非法状态。现在为时已晚。任何尝试都会导致servletcontainer抛出IllegalStateException: response already committed

要解决此问题,您需要将此部分代码放在JSP文件的最顶层,并祈祷此时尚未提交响应(这通常发生在向响应写入大约2KB数据之后)取决于servletcontainer配置)。但是,JSP仍然是工作的错误位置,您应该在控制器中执行此操作,之前将响应转发到JSP(或者从模型内部指示控制器以某种方式完成工作,当你使用MVC框架时。)