添加导致 java.lang.IllegalStateException:提交响应后无法创建会话

发布于 2024-12-14 13:54:33 字数 980 浏览 3 评论 0原文

添加 后,我在一个非常简单的 JSF 2 页面中遇到以下异常:

java.lang.IllegalStateException: Cannot create a session after the response has been committed
    at org.apache.catalina.connector.Request.doGetSession(Request.java:2758)
    at org.apache.catalina.connector.Request.getSession(Request.java:2268)

我在 Tomcat 7.0.22 和 JDK 上使用 Mojarra 2.1.3 和 PrimeFaces3.0M4 7.

该页面是一个非常基本的数据表:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
<h:head>

</h:head>
<h:body>
    <h:form>        
        <p:dataTable var="car" value="#{tableBean.cars}">

                 ......
        </p:dataTable>
    </h:form>
</h:body>
</html>

该页面在浏览器上正确显示,但在控制台上我看到异常。如果我删除 ,异常就会消失。

这是如何引起的以及如何解决?

I'm facing the following exception in a very simple JSF 2 page after adding <h:form>:

java.lang.IllegalStateException: Cannot create a session after the response has been committed
    at org.apache.catalina.connector.Request.doGetSession(Request.java:2758)
    at org.apache.catalina.connector.Request.getSession(Request.java:2268)

I'm using Mojarra 2.1.3 and PrimeFaces3.0M4, on Tomcat 7.0.22 and JDK 7.

The page is a very basic data table:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:p="http://primefaces.org/ui">
<h:head>

</h:head>
<h:body>
    <h:form>        
        <p:dataTable var="car" value="#{tableBean.cars}">

                 ......
        </p:dataTable>
    </h:form>
</h:body>
</html>

The page shows correctly on the browser, but on the console I see the exception. The Exception does disappear if I remove the <h:form>.

How is this caused and how can I solve it?

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

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

发布评论

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

评论(5

神爱温柔 2024-12-21 13:54:33

这是一个已知问题,您已将其报告为问题 2215。当响应缓冲区溢出(由于内容较大)并且在创建会话之前提交响应时,就会发生这种情况。这是 Mojarra 过于热心地尝试尽可能推迟“不必要的”会话创建的结果(尽管这本身就是一件好事)。

在他们修复此问题之前,有几种解决方法:

  1. 创建一个Filter,它可以HttpServletRequest#getSession()FilterChain#doFilter()。优点:无需更改 JSF 配置/代码。缺点:当您也想避免自己创建不必要的会话时。

  2. 调用 ExternalContext#getSession() 在 bean 的(post)构造函数或 preRenderView 侦听器中使用 true。优点:其实没什么。缺点:太老套了。

  3. web.xml 添加名称为 com.sun.faces.writeStateAtFormEnd 且值为 false 的上下文参数。优点:与 #1 和 #2 相比,将真正避免不必要的会话创建。缺点:响应现在将完全缓冲在内存中,直到到达 为止。如果您的表单不是很大,那么影响应该很小。然而,如果您的 在视图中启动相对较晚,它仍然会失败。这可以与 #4 结合使用。

  4. 添加名称为 javax.faces.FACELETS_BUFFER_SIZE 的上下文参数和 Facelets 响应缓冲区大小的值(以字节为单位,例如 65535 表示 64KB),以便整个HTML 输出或至少 (参见 #3)适合响应缓冲区。优点/缺点,请参阅 #3。

  5. 将名称为 javax.faces.STATE_SAVING_METHOD 且值为 client 的上下文参数添加到 web.xml。优点:除非您有会话范围的 bean,否则根本不会创建会话。它还可以立即解决潜在的 ViewExpiredException 情况。缺点:增加网络带宽使用。如果您使用部分状态保存,那么影响应该很小。

至于为什么删除 后问题就消失了,这是因为不需要创建会话来存储视图状态。


更新:根据重复的问题 2277 已修复此问题自 Mojarra 2.1.8 起。因此,您也可以至少升级到该版本。

This is a known problem and has been reported by yours truly as issue 2215. This will occur when the response buffer has overflowed (due to large content) and the response is been committed before the session is been created. This is result of bit overzealous attempts of Mojarra to postpone "unnecessary" session creation as much as possible (which is at its own a Good Thing though).

Until they get it fixed, there are several workarounds:

  1. Create a Filter which does HttpServletRequest#getSession() before FilterChain#doFilter(). Advantage: no need to change JSF configuration/code. Disadvantage: when you want to avoid unnecessary session creation yourself as well.

  2. Call ExternalContext#getSession() with true in bean's (post)constructor or preRenderView listener. Advantage: actually, nothing. Disadvantage: too hacky.

  3. Add a context parameter with name of com.sun.faces.writeStateAtFormEnd and value of false to web.xml. Advantage: unnecessary session creation will be really avoided as opposed to #1 and #2. Disadvantage: response will now be fully buffered in memory until </h:form> is reached. If your forms are not extremely large, the impact should however be minimal. It would however still fail if your <h:form> starts relatively late in the view. This may be combined with #4.

  4. Add a context parameter with name of javax.faces.FACELETS_BUFFER_SIZE and a value of the Facelets response buffer size in bytes (e.g. 65535 for 64KB) so that the entire HTML output or at least the <h:form> (see #3) fits in the response buffer. Advantage/disadvantage, see #3.

  5. Add a context parameter with name of javax.faces.STATE_SAVING_METHOD and value of client to web.xml. Advantage: session will not be created at all unless you have session scoped beans. It also immediately solves potential ViewExpiredException cases. Disadvantage: increased network bandwidth usage. If you're using partial state saving, then the impact should however be minimal.

As to why the problem disappears when you remove <h:form>, this is because no session needs to be created in order to store the view state.


Update: this has as per the duplicate issue 2277 been fixed since Mojarra 2.1.8. So, you can also just upgrade to at least that version.

浅沫记忆 2024-12-21 13:54:33

随着 javax.faces 昨天发布的新版本 2.1.21,这个问题似乎已经消失了。
声明新版本:

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.1.21</version>
</dependency>

并替换 glassfish 模块文件夹中的 javax.faces.jar,替换新版本 2.1.21 的 javax.faces.jar。

With the new version 2.1.21 released yesterday of javax.faces this problem seems to have disappeared.
Declare the new version:

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>javax.faces</artifactId>
    <version>2.1.21</version>
</dependency>

and replace the javax.faces.jar in the glassfish modules folder replacing the javax.faces.jar for the new version 2.1.21.

触ぅ动初心 2024-12-21 13:54:33

就我而言(myfaces-2.2.8 和 Tomcat 8.0.23),问题是 web.xmlwelcome-file 中的拼写错误。
在调试时,我看到 Tomcat 按预期创建了 404,但不知何故 myfaces 尝试在之后访问会话,这导致了 java.lang.IllegalStateException: Cannot create a session after the response has been commited
web.xmlwelcome-file 中使用有效页面解决了我的问题。

In my case (myfaces-2.2.8 & Tomcat 8.0.23) the Problem was a typo in the welcome-file of web.xml.
While debugging i saw, that Tomcat created as expected a 404, but somehow myfaces tried to access afterwards the Session, which caused then a java.lang.IllegalStateException: Cannot create a session after the response has been committed.
Using a valid page in welcome-file of web.xml fixed the Problem for me.

清晨说晚安 2024-12-21 13:54:33

您可能需要在 h:form 元素之前和之后添加 ,再加上添加指向 jsf 标签的 html 标签的链接,

<html xmlns:f="http://java.sun.com/jsf/core">

以使其正常工作。

You may need to add an <f:view> and </f:view> before and after h:form elements, plus add the link to you html tag for jsf tags

<html xmlns:f="http://java.sun.com/jsf/core">

for this to work.

灯下孤影 2024-12-21 13:54:33

如果您使用 Spring MVC 并且由 Spring Forms 进行调用,那么我们应该使用 GET 方法而不是 POST(获取数据),并且不应该有我们可以使用的输入字段。

If you are using Spring MVC and call is made by Spring Forms then we should use GET method instead of POST(to fetch data) and there should be no input field we can use intead.

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