47

添加后,我在一个非常简单的 JSF 2 页面中遇到以下异常<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。

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

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

这是如何引起的,我该如何解决?

4

5 回答 5

83

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

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

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

  2. ExternalContext#getSession()使用truebean 的(后)构造函数或preRenderView侦听器调用。优点:实际上,什么都没有。缺点:太hacky。

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

  4. 添加一个上下文参数,其名称javax.faces.FACELETS_BUFFER_SIZE和值是 Facelets 响应缓冲区大小(以字节为单位)(例如6553564KB),以便整个 HTML 输出或至少<h:form>(参见 #3)适合响应缓冲区。优势/劣势,见#3。

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

至于为什么删除时问题消失了<h:form>,这是因为不需要创建会话来存储视图状态。


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

于 2011-11-09T22:09:14.837 回答
6

随着昨天发布的 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。

于 2013-04-10T15:10:59.763 回答
3

就我而言(myfaces-2.2.8 和 Tomcat 8.0.23),问题welcome-fileweb.xml. 在调试时我看到,Tomcat 按预期创建了一个 404,但不知何故 myfaces 试图在之后访问 Session,这导致了一个java.lang.IllegalStateException: Cannot create a session after the response has been committed. 使用有效的页面welcome-fileweb.xml我解决了问题。

于 2015-07-29T11:48:23.813 回答
0

您可能需要在元素之前和之后添加一个<f:view></f:view> 之前和之后h:form的元素,并为 jsf 标记添加指向您的 html 标记的链接

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

为此工作。

于 2017-06-16T20:19:58.667 回答
-1

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

于 2015-02-12T07:30:09.200 回答