Dodawanie przyczyn.lang.IllegalStateException: nie można utworzyć sesji po zatwierdzeniu odpowiedzi

W bardzo prostej stronie JSF 2 Po dodaniu <h:form> pojawia się następujący wyjątek:

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)
Używam Mojarra 2.1.3 i PrimeFaces3. 0M4, na Tomcat 7.0.22 i JDK 7.

Strona jest bardzo podstawową tabelą danych:

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

Strona wyświetla się poprawnie w przeglądarce, ale na konsoli widzę wyjątek. Wyjątek zniknie, jeśli usunę <h:form>.

Jak to jest spowodowane i jak Mogę to rozwiązać?

Author: BalusC, 2011-11-10

5 answers

Jest to znany problem i został zgłoszony przez Ciebie jako Numer 2215 . Nastąpi to, gdy bufor odpowiedzi przepełni się (z powodu dużej zawartości) i odpowiedź zostanie zatwierdzona przed utworzeniem sesji. Jest to wynik nieco nadgorliwych prób Mojarry, aby odłożyć" niepotrzebne " tworzenie sesji w jak największym stopniu (co samo w sobie jest jednak dobrą rzeczą).

Dopóki go nie naprawią, istnieje kilka obejścia:

  1. Utwórz Filter, które robi HttpServletRequest#getSession() przed FilterChain#doFilter(). Zaleta: nie ma potrzeby zmiany konfiguracji/kodu JSF. Wada: gdy chcesz uniknąć niepotrzebnego tworzenia sesji również samodzielnie.

  2. Call ExternalContext#getSession() Z true w konstruktorze (post)lub preRenderView. Zaleta: właściwie nic. Wada: zbyt szorstka.

  3. Dodaj parametr kontekstowy o nazwie com.sun.faces.writeStateAtFormEnd i wartości false do web.xml. Zaleta: niepotrzebne tworzenie sesji będzie naprawdę uniknąć w przeciwieństwie do #1 i #2. Wadą: odpowiedź będzie teraz w pełni buforowana w pamięci do momentu osiągnięcia </h:form>. Jeśli Twoje formularze nie są zbyt duże, wpływ powinien być jednak minimalny. Jednak i tak zawiedzie, jeśli twój <h:form> zacznie się stosunkowo późno w widoku. Można to połączyć z #4.

  4. Dodaj parametr kontekstowy o nazwie javax.faces.FACELETS_BUFFER_SIZE i wartości rozmiaru bufora odpowiedzi Facelets w bajtach (np. 65535 dla 64KB) tak, aby całe wyjście HTML lub przynajmniej <h:form> (patrz #3) zmieściło się w buforze odpowiedzi. Zaleta/wada, patrz #3.

  5. Dodaj parametr kontekstowy o nazwie javax.faces.STATE_SAVING_METHOD i wartości client do web.xml. Zaleta: sesja nie zostanie utworzona w ogóle, chyba że masz fasolki z zakresem sesji. To również natychmiast rozwiązuje potencjalne ViewExpiredException przypadki. Wadą: Zwiększone wykorzystanie przepustowości sieci. Jeśli używasz częściowego zapisywania stanu, wpływ powinien być jednak Minimalne.

Dlaczego problem znika po usunięciu <h:form>, dzieje się tak dlatego, że nie trzeba tworzyć sesji, aby zapisać stan widoku.


Update: to ma jak na duplikat issue 2277 został naprawiony od Mojarra 2.1.8. Możesz więc po prostu uaktualnić do co najmniej tej wersji.

 83
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-15 15:11:29

Z nową wersją 2.1.21 wydaną wczoraj javax.twarze ten problem wydaje się zniknąć. Zadeklaruj nową wersję:

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

I zastąp javaxa.twarze.jar w folderze modułów glassfish zastępujący javax.twarze.jar dla nowej wersji 2.1.21.

 6
Author: Gaspar Kuhnen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-10 15:10:59

W moim przypadku (myfaces-2.2.8 & Tomcat 8.0.23) problemem była literówka w welcome-file z web.xml. Podczas debugowania zobaczyłem, że Tomcat stworzył zgodnie z oczekiwaniami 404, ale jakoś myfaces próbowali uzyskać dostęp po sesji, co spowodowało wtedy java.lang.IllegalStateException: Cannot create a session after the response has been committed. Użycie poprawnej strony w welcome-file z web.xml naprawiło Problem dla mnie.

 3
Author: hinneLinks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-29 11:48:23

Może być konieczne dodanie elementów <f:view> i </f:view> przed i po h:form oraz dodanie linku do znacznika html dla znaczników jsf

<html xmlns:f="http://java.sun.com/jsf/core">
Żeby to zadziałało.
 0
Author: joeblow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-16 20:22:41

Jeśli używasz Spring MVC i wywołanie jest wykonywane przez Spring Forms, powinniśmy użyć metody GET zamiast POST (do pobierania danych) i nie powinno być pola wejściowego, którego możemy użyć intead.

 -1
Author: user2645432,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 07:30:09