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

发布于 2024-10-05 20:08:48 字数 1591 浏览 5 评论 0原文

我有一个带有 ac: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>

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

<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。 为什么此更改会导致异常,特别是考虑到所涉及的行(重定向,而不是更改/绑定的类实例)导致了问题?

后端进行了相应的更改,引用我的新的包含“通用”类中的属性来满足旧的功能。我知道这是有效的,因为除了我正在写的内容之外,所有相关功能都有效。

网上研究表明: - 提交后我无法重定向/转发。那我以前是怎么做到的呢? - 尝试刷新已清除的缓冲区会导致此情况。与旧的(第一个)实现相比,是什么变化使它现在被清除了? - 页面缓冲区的大小需要更大。这是我不明白的问题,并且非常希望 stackoverflow 社区能够解决这个问题;我可以看到我的新类导致大小发生变化,需要进行更改才能处理。

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

首先也是最重要的,始终按照标记答案的描述在代码中设置情况。但是...如果您遇到困难并且不想这样做,这里有一个快速解决方案:javascript!

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

I had a JSP file with a c:redirect tag that would forward along a user to another page.

<!-- 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>

The old implementation of the command object is needs updating (where I come in). The way I'm doing so is by creating a generic "search result" object which contains an instance of that old object (for now). I get that instance through a property in that generic class, so my code is now this:

<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>

Each of those three tries all result in IllegalStateExceptions of some sort. Why does this change cause the exception, especially considering that the lines involved -- the redirect, not the changed/bound class instances -- are causing the problem?

Back-end changes were made accordingly, referencing the property within my new encompassing "generic" class to satisfy the old functionality. I know this works because all related functionality, beside what I'm writing about, works.

Research online indicates:
- I can't redirect/forward after a submission has already been submitted. Then how was I able to do it before?
- Attempt to flush an already-cleared buffer causes this. What changed that makes it cleared now as opposed to the older (first) implementation?
- The size of the page's buffer needs to be bigger. THIS is one I don't understand and would really love for the stackoverflow community to address; I can see my new class causing size changes that would need changes to be dealt with.

------- ANOTHER ANSWER! -------

First and foremost, ALWAYS SET UP THE SITUATION IN THE CODE as described by the marked answer. However... if you're stuck and don't want to do that, here's a quick fix: javascript!

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

挽袖吟 2024-10-12 20:08:48

JSP 是响应的一部分。您正在尝试更改 JSP 中的响应目标,而不是控制器中的响应目标。如果您在 JSP 中中途执行此操作,则为时已晚,因为 HTTP 响应标头可能已经发送(响应随后处于“已提交”状态)。这是一个无法返回的点,也是更改响应的非法状态。那时就太晚了。任何尝试都会导致 servlet 容器抛出 IllegalStateException:响应已提交

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

JSP is part of the response. You're attempting to change the response destination in a JSP instead of in a controller. If you do this halfway in a JSP, then it's too late, because the HTTP response headers may already have been sent (the response is then in committed state). This is a point of no return and an illegal state for changing the response. It's too late then. Any attempt will result in the servletcontainer to throw IllegalStateException: response already committed.

To fix this, you need to put this piece code in the very top of JSP file and pray that the response hasn't already been committed at that point (which will usually happen after writing about 2KB of data to the response, depending on the servletcontainer config). However, JSP is still the wrong place for the job, you should rather do this in the controller, before forwarding the response to the JSP (or to instruct from within the model the controller somehow to do the job, when you're using a MVC framework).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文