2011-11-09 26 views
46

estoy frente a la siguiente excepción de una manera muy sencilla página JSF 2 después de añadir <h:form>:<h:form> provoca java.lang.IllegalStateException: No se puede crear una sesión después de que la respuesta ha sido cometido

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) 

estoy utilizando Mojarra 2.1.3 y PrimeFaces3.0M4, en Tomcat 7.0.22 y JDK 7.

La página es una tabla de datos muy básicos:

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

la página se muestra correctamente en el navegador, pero en la consola veo la excepción. La excepción desaparece si elimino el <h:form>.

¿Cómo se causa esto y cómo puedo solucionarlo?

Respuesta

82

Este es un problema conocido y ha sido reportado por los usuarios realmente como issue 2215. Esto ocurrirá cuando el búfer de respuesta se haya desbordado (debido a un gran contenido) y la respuesta se haya confirmado antes de que se haya creado la sesión. Esto es el resultado de los intentos poco entusiastas de Mojarra para posponer la creación de sesión "innecesaria" tanto como sea posible (lo cual es en sí mismo una buena cosa).

Hasta que te lo arreglen, hay varias soluciones:

  1. Crear una Filter, que hace HttpServletRequest#getSession() antes FilterChain#doFilter(). Ventaja: no es necesario cambiar la configuración/código JSF. Desventaja: cuando también quiere evitar la creación innecesaria de sesiones.

  2. Llamada ExternalContext#getSession() con true en el constructor (post) de bean o preRenderView oyente. Ventaja: en realidad, nada. Desventaja: demasiado hacky.

  3. Añadir un parámetro de contexto con el nombre de com.sun.faces.writeStateAtFormEnd y el valor de false-web.xml. Ventaja: realmente se evitará la creación innecesaria de sesiones en lugar de # 1 y # 2. Desventaja: la respuesta ahora estará completamente almacenada en la memoria hasta que se alcance el </h:form>. Si sus formularios no son extremadamente grandes, el impacto debería ser mínimo. Sin embargo, aún fallaría si su <h:form> comienza relativamente tarde en la vista. Esto se puede combinar con el # 4.

  4. Añadir un parámetro de contexto con el nombre de javax.faces.FACELETS_BUFFER_SIZE y un valor de la respuesta de tamaño de búfer Facelets en bytes (por ejemplo 65535 para 64KB) de modo que toda la salida HTML o al menos la <h:form> (ver # 3) encaja en la respuesta buffer. Ventaja/desventaja, ver # 3.

  5. Agregue un parámetro de contexto con el nombre de javax.faces.STATE_SAVING_METHOD y el valor de client a web.xml. Ventaja: la sesión no se creará en absoluto a menos que tenga beans de ámbito de sesión. También soluciona casos potenciales ViewExpiredException inmediatamente. Desventaja: aumento en el uso del ancho de banda de la red. Si está utilizando el ahorro de estado parcial, entonces el impacto debería ser mínimo.

cuanto a por qué el problema desaparece cuando se quita <h:form>, esto se debe a que no hay una sesión tiene que ser creado con el fin de almacenar el estado de vista.


actualización: esto tiene según el duplicado issue 2277 han corregido desde Mojarra 2.1.8. Entonces, también puedes simplemente actualizar a al menos esa versión.

+1

gracias! parece que este problema se resolverá con Mojarra 2.1.8 (http://java.net/jira/browse/JAVASERVERFACES-2277) que debería ser lanzado pronto – wemu

+1

Lea toda la JIRA, parece que el problema todavía está presente , 2.1.16 –

+0

Tuve un problema similar, y mientras estoy usando 2.1.13, el problema estaba presente. Implementar el consejo # 3, sin embargo, lo resolvió. –

5

Con la nueva versión 2.1.21 lanzada ayer de javax.faces, este problema parece haber desaparecido. declarar la nueva versión:

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

y reemplazar el javax.faces.jar en la carpeta de módulos glassfish sustitución de la javax.faces.jar para la nueva versión 2.1.21.

-1

Si está utilizando Spring MVC y la llamada está hecha por Spring Forms, entonces debemos usar el método GET en lugar de POST (para buscar datos) y no debería haber ningún campo de entrada que podamos usar intead.

+0

\t \t \t \t \t \t View All Hospitals \t \t \t \t \t – user2645432

2

En mi caso (myfaces-2.2.8 & Tomcat 8.0.23) el problema era un error ortográfico en el welcome-file de web.xml. Mientras estaba depurando, vi que Tomcat creó como se esperaba un 404, pero de alguna manera mis caras intentaron acceder posteriormente a la sesión, lo que provocó un java.lang.IllegalStateException: Cannot create a session after the response has been committed. Usando una página válida en welcome-file de web.xml solucionó el problema.

0

Es posible que necesite añadir una <f:view> y </f:view> antes y después de h:form elementos, además de añadir el enlace a usted etiqueta HTML para las etiquetas jsf

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

para que esto funcione.

Cuestiones relacionadas