#forms #session #jsf #jsf-2 #illegalstateexception
#формы #сеанс #jsf #jsf-2 #исключение illegalstateexception
Вопрос:
Я сталкиваюсь со следующим исключением на очень простой странице 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>
.
Чем это вызвано и как я могу это решить?
Ответ №1:
Это известная проблема, о которой ваш покорный слуга сообщил как о проблеме 2215. Это произойдет, когда буфер ответов переполнится (из-за большого содержимого) и ответ будет зафиксирован до создания сеанса. Это результат немного переусердствовавших попыток Mojarra максимально отложить создание «ненужного» сеанса (что само по себе, впрочем, хорошо).
Пока они не исправят это, существует несколько обходных путей:
-
Создайте,
Filter
который делает этоHttpServletRequest#getSession()
раньшеFilterChain#doFilter()
. Преимущество: нет необходимости изменять конфигурацию / код JSF. Недостаток: когда вы также хотите избежать ненужного создания сеанса самостоятельно. -
Вызовите
ExternalContext#getSession()
сtrue
помощью конструктора (post) компонента илиpreRenderView
прослушивателя. Преимущество: фактически, ничего. Недостаток: слишком хакерский. -
Добавьте параметр контекста с именем
com.sun.faces.writeStateAtFormEnd
и значениемfalse
вweb.xml
. Преимущество: ненужное создание сеанса будет действительно предотвращено в отличие от # 1 и # 2. Недостаток: ответ теперь будет полностью буферизован в памяти до</h:form>
достижения. Если ваши формы не очень большие, влияние, однако, должно быть минимальным. Однако это все равно приведет к сбою, если ваш<h:form>
запуск относительно поздно в представлении. Это может быть объединено с #4. -
Добавьте параметр контекста с именем
javax.faces.FACELETS_BUFFER_SIZE
и значением размера буфера ответов Facelets в байтах (например,65535
для 64 КБ), чтобы весь вывод HTML или, по крайней мере,<h:form>
(см. # 3) помещался в буфер ответов. Преимущество / недостаток, см. #3. -
Добавьте параметр контекста с именем
javax.faces.STATE_SAVING_METHOD
и значениемclient
вweb.xml
. Преимущество: сеанс вообще не будет создан, если у вас нет компонентов в области сеанса. Это также немедленно решает потенциальныеViewExpiredException
случаи. Недостаток: повышенное использование пропускной способности сети. Однако, если вы используете частичное сохранение состояния, влияние должно быть минимальным.
Что касается того, почему проблема исчезает при удалении <h:form>
, это потому, что для сохранения состояния просмотра не нужно создавать сеанс.
Обновление: это, согласно дублирующейся проблеме 2277, было исправлено начиная с Mojarra 2.1.8. Таким образом, вы также можете просто обновиться по крайней мере до этой версии.
Комментарии:
1. Спасибо! похоже, эта проблема будет решена с помощью Mojarra 2.1.8 ( java.net/jira/browse/JAVASERVERFACES-2277 ), который должен быть выпущен в ближайшее время
2. Прочитайте весь JIRA, кажется, что проблема все еще существует, 2.1.16
3. У меня была похожая проблема, и пока я использую 2.1.13, проблема существовала. Однако реализация рекомендации # 3 решила проблему.
Ответ №2:
С новой версией javax.faces 2.1.21, выпущенной вчера, эта проблема, похоже, исчезла. Объявите новую версию:
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.1.21</version>
</dependency>
и замените javax.faces.jar в папке glassfish modules заменяет javax.faces.jar для новой версии 2.1.21.
Ответ №3:
В моем случае (myfaces-2.2.8 amp; Tomcat 8.0.23) проблема заключалась в опечатке в welcome-file
of web.xml
. Во время отладки я увидел, что Tomcat создал, как и ожидалось, 404, но каким-то образом myfaces попытался впоследствии получить доступ к сеансу, что вызвало затем java.lang.IllegalStateException: Cannot create a session after the response has been committed
. Использование допустимой страницы в welcome-file
of web.xml
исправило проблему для меня.
Ответ №4:
Возможно, вам потребуется добавить элементы <f:view>
и </f:view>
до и после h:form
, а также добавить ссылку на ваш html-тег для тегов jsf
<html xmlns:f="http://java.sun.com/jsf/core">
чтобы это сработало.
Ответ №5:
Если вы используете Spring MVC и вызов выполняется Spring Forms, тогда мы должны использовать метод GET вместо POST (для извлечения данных), и не должно быть поля ввода, которое мы могли бы использовать внутри.
Комментарии:
1. <форма: метод формы=»получить» действие= «#» идентификатор=»viewAllHospital» class=»validateForm» ModelAttribute=»hccHospitalUserInfoForm»> <a href=»/view/B2CSuperAdminProfileComponentController?viewAllHospital=true»> Просмотреть все больницы</a> </form: форма>