webentwicklung-frage-antwort-db.com.de

Das Hinzufügen von <h: form> führt zu Java.lang.IllegalStateException: Es kann keine Sitzung erstellt werden, nachdem die Antwort festgeschrieben wurde

Nach dem Hinzufügen von <h:form> steht mir auf einer sehr einfachen JSF 2-Seite die folgende Ausnahme bevor:

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)

Ich verwende Mojarra 2.1.3 und PrimeFaces3.0M4 auf Tomcat 7.0.22 und JDK 7.

Die Seite ist eine sehr grundlegende Datentabelle:

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

Die Seite wird im Browser richtig angezeigt, aber auf der Konsole wird die Ausnahme angezeigt. Die Ausnahme verschwindet, wenn ich den <h:form> entferne.

Wie wird das verursacht und wie kann ich es lösen?

47
Pier Luigi

Dies ist ein bekanntes Problem und wurde von Ihnen wirklich als Ausgabe 2215 gemeldet. Dies tritt auf, wenn der Antwortpuffer (aufgrund von großem Inhalt) übergelaufen ist und die Antwort festgeschrieben wurde, bevor die Sitzung erstellt wurde. Dies ist das Ergebnis von übereifrigen Versuchen von Mojarra, die "unnötige" Sitzungserstellung so weit wie möglich zu verschieben (was allerdings eine gute Sache ist).

Bis es behoben wird, gibt es mehrere Problemumgehungen:

  1. Erstellen Sie eine Filter, die HttpServletRequest#getSession() vor FilterChain#doFilter() tut. Vorteil: JSF-Konfiguration/Code muss nicht geändert werden. Nachteil: wenn Sie selbst unnötige Sitzungserstellung vermeiden möchten.

  2. Rufen Sie ExternalContext#getSession() mit true im Bean-Konstruktor (post) oder preRenderView-Listener auf. Vorteil: eigentlich nichts. Nachteil: zu hackig.

  3. Fügen Sie einen Kontextparameter mit dem Namen com.Sun.faces.writeStateAtFormEnd und dem Wert von false zu web.xml hinzu. Vorteil: unnötige Sitzungserstellung wird im Gegensatz zu # 1 und # 2 wirklich vermieden. Nachteil: Die Antwort wird jetzt vollständig im Speicher zwischengespeichert, bis </h:form> erreicht ist. Wenn Ihre Formulare nicht sehr groß sind, sollte die Auswirkung jedoch minimal sein. Es würde jedoch immer noch fehlschlagen, wenn Ihr <h:form> relativ spät in der Ansicht beginnt. Dies kann mit # 4 kombiniert werden.

  4. Fügen Sie einen Kontextparameter mit dem Namen javax.faces.FACELETS_BUFFER_SIZE und einem Wert der Antwortpuffergröße von Facelets in Bytes hinzu (z. B. 65535 für 64 KB), so dass die gesamte HTML-Ausgabe oder zumindest der <h:form> (siehe # 3) in den Antwortpuffer passt. Vorteil/Nachteil, siehe Punkt 3.

  5. Fügen Sie einen Kontextparameter mit dem Namen javax.faces.STATE_SAVING_METHOD und dem Wert von client zu web.xml hinzu. Vorteil: Sitzung wird nicht erstellt, es sei denn, Sie haben Beans mit Sitzungsbereich. Es löst auch sofort mögliche ViewExpiredException Fälle. Nachteil: erhöhte Netzwerkbandbreite. Wenn Sie eine teilweise Zustandsersparnis verwenden, sollte die Auswirkung jedoch minimal sein.

Das Problem verschwindet, wenn Sie <h:form> entfernen. Dies liegt daran, dass zum Speichern des Ansichtsstatus keine Sitzung erstellt werden muss.


Update: Dies wurde gemäß dem Duplikat issue 2277 seit Mojarra 2.1.8 behoben. Sie können also auch mindestens auf diese Version upgraden.

83
BalusC

Mit der neuen Version 2.1.21, die gestern von javax.faces veröffentlicht wurde, scheint dieses Problem verschwunden zu sein . Deklarieren Sie die neue Version:

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

und ersetzen Sie die Datei "javax.faces.jar" im Ordner "glassfish modules" und ersetzen Sie die Datei "javax.faces.jar" für die neue Version 2.1.21.

6
Gaspar Kuhnen

In meinem Fall (myfaces-2.2.8 & Tomcat 8.0.23) war das Problem ein Tippfehler im welcome-file von web.xml. Beim Debuggen sah ich, dass Tomcat erwartungsgemäß eine 404 erstellt hatte, aber irgendwie versuchte myfaces nachher darauf zuzugreifen Session, die dann einen Java.lang.IllegalStateException: Cannot create a session after the response has been committed verursacht hat. Durch Verwendung einer gültigen Seite in welcome-file von web.xml wurde das Problem für mich behoben.

3
hinneLinks

Möglicherweise müssen Sie vor und nach den <f:view>-Elementen einen </f:view>- und einen h:form-Element hinzufügen. Außerdem muss der Link zu Ihrem html-Tag für jsf-Tags hinzugefügt werden

<html xmlns:f="http://Java.Sun.com/jsf/core">

damit dies funktioniert.

0
joeblow