Добавлениевызывает java.lang.IllegalStateException: не может создать сеанс после того, как ответ был передан - PullRequest
47 голосов
/ 10 ноября 2011

Я сталкиваюсь со следующим исключением на очень простой странице 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)

Я использую Mojarra 2.1.3 и PrimeFaces3.0M4 на Tomcat 7.0.22и JDK 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>

Страница правильно отображается в браузере, но на консоли я вижу исключение.Исключение исчезает, если я удаляю <h:form>.

Как это вызвано и как я могу его решить?

Ответы [ 5 ]

83 голосов
/ 10 ноября 2011

Это известная проблема, о которой вы действительно сообщаете как проблема 2215 .Это произойдет, если буфер ответов переполнен (из-за большого содержимого), и ответ будет зафиксирован до создания сеанса.Это является результатом чрезмерно усердных попыток Мохарры максимально отложить «ненужное» создание сеанса (хотя это само по себе хорошо).

Пока они не исправят это, есть несколько обходных путей:

  1. Создайте Filter, что делает HttpServletRequest#getSession() до FilterChain#doFilter().Преимущество: нет необходимости изменять конфигурацию / код JSF.Недостаток: когда вы также хотите избежать ненужного создания сеанса.

  2. Вызов ExternalContext#getSession() с true в конструкторе (post) компонента или preRenderViewслушатель.Преимущество: на самом деле, ничего.Недостаток: слишком хакерский.

  3. Добавьте параметр контекста с именем com.sun.faces.writeStateAtFormEnd и значением от false до web.xml.Преимущество: действительно нужно избегать ненужного создания сеанса, в отличие от # 1 и # 2.Недостаток: ответ теперь будет полностью буферизован в памяти до достижения </h:form>.Если ваши формы не очень большие, влияние должно быть минимальным.Однако он все равно потерпит неудачу, если ваш <h:form> стартует относительно поздно в представлении.Это может быть объединено с # 4.

  4. Добавьте параметр контекста с именем javax.faces.FACELETS_BUFFER_SIZE и значением размера буфера ответа Facelets в байтах (например, 65535 для 64 КБ), такчто весь вывод HTML или хотя бы <h:form> (см. # 3) помещается в буфер ответа.Преимущество / недостаток, см. # 3.

  5. Добавьте параметр контекста с именем javax.faces.STATE_SAVING_METHOD и значением от client до web.xml.Преимущество: сессия не будет создана вообще, если у вас нет сессионных компонентов.Это также немедленно решает потенциальные ViewExpiredException случаев.Недостаток: увеличение пропускной способности сети.Если вы используете частичное сохранение состояния, то влияние должно быть минимальным.

Относительно того, почему проблема исчезает при удалении <h:form>, это связано с тем, что сеанс не требуетсясоздан для хранения состояния просмотра.


Обновление : в соответствии с дубликатом проблема 2277 была исправлена ​​начиная с Mojarra 2.1.8.Таким образом, вы также можете просто обновить хотя бы до этой версии.

6 голосов
/ 10 апреля 2013

В новой версии javax.faces 2.1.21, выпущенной вчера, эта проблема, похоже, исчезла. Объявите новую версию:

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

и замените javax.faces.jar в папке модулей glassfish, заменив javax.faces.jar для новой версии 2.1.21.

3 голосов
/ 29 июля 2015

В моем случае (myfaces-2.2.8 и Tomcat 8.0.23) проблема заключалась в опечатке в welcome-file из web.xml. Во время отладки я увидел, что Tomcat создал, как и ожидалось, 404, но каким-то образом myfaces попытался получить доступ к сеансу, что привело к java.lang.IllegalStateException: Cannot create a session after the response has been committed. Использование действующей страницы в welcome-file из web.xml решило проблему для меня.

0 голосов
/ 16 июня 2017

Вам может потребоваться добавить <f:view> и </f:view> до и после h:form элементов, а также добавить ссылку на ваш html-тег для jsf-тегов

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

, чтобы это работало.

0 голосов
/ 12 февраля 2015

Если вы используете Spring MVC и вызов осуществляется Spring Forms, тогда мы должны использовать метод GET вместо POST (для выборки данных), и не должно быть никакого поля ввода, которое мы могли бы использовать intead.

...