添加 <h:form>导致 java.lang.IllegalStateException: 响应提交后无法创建会话 [英] Adding <h:form> causes java.lang.IllegalStateException: Cannot create a session after the response has been committed

查看:49
本文介绍了添加 <h:form>导致 java.lang.IllegalStateException: 响应提交后无法创建会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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)

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

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>

页面在浏览器上正确显示,但在控制台上我看到了异常.如果我删除 <h:form>,异常就会消失.

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?

推荐答案

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

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. 创建一个 Filter,它执行 HttpServletRequest#getSession()FilterChain#doFilter().优点:无需更改 JSF 配置/代码.缺点:当您还想避免自己创建不必要的会话时.

  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.

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

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

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

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.

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

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.

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

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.

至于为什么去掉<h:form>后问题就消失了,这是因为不需要创建会话来存储视图状态.

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.

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

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.

这篇关于添加 &lt;h:form&gt;导致 java.lang.IllegalStateException: 响应提交后无法创建会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆