47 votes

L'ajout de <h:form> provoque une java.lang.IllegalStateException : Impossible de créer une session après que la réponse ait été validée.

Je suis confronté à l'exception suivante dans une page JSF 2 très simple après avoir ajouté <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)

J'utilise Mojarra 2.1.3 et PrimeFaces3.0M4, sur Tomcat 7.0.22 et JDK 7.

La page est un tableau de données très basique :

<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 page s'affiche correctement dans le navigateur, mais dans la console, je vois l'exception. L'exception disparaît si je supprime le <h:form> .

Comment cela se produit-il et comment puis-je le résoudre ?

83voto

BalusC Points 498232

C'est un problème connu et a été rapporté par votre serviteur, en tant que question 2215. Cela se produit lorsque le tampon de réponse a débordé (à cause de la grande contenu) et la réponse est été commis avant la session est créé. C'est la suite de bits excès de zèle des tentatives de Mojarra de reporter "inutiles" de la session de création autant que possible (ce qui est à sa propre une Bonne Chose).

Jusqu'à ce qu'il fixe, il existe plusieurs solutions:

  1. Créer un Filter qui n' HttpServletRequest#getSession() avant FilterChain#doFilter(). Avantage: pas besoin de changer de configuration de JSF/code. Inconvénient: quand vous voulez pour éviter la création de session vous-même ainsi.

  2. Appelez ExternalContext#getSession() avec true dans l'haricot (post), le constructeur ou l' preRenderView auditeur. Avantage: en fait, rien. Inconvénient: trop hacky.

  3. Ajouter un paramètre de contexte avec le nom de l' com.sun.faces.writeStateAtFormEnd et la valeur de false de web.xml. Avantage: inutile de création de session sera vraiment évité par opposition à #1 et #2. Inconvénient: la réponse sera désormais entièrement en mémoire tampon jusqu'à ce qu' </h:form> est atteint. Si vos formulaires ne sont pas très grandes, l'impact devrait toutefois être minime. Toutefois, il serait encore échouer si votre <h:form> commence relativement tard dans la vue. Ceci peut être combiné avec le n ° 4.

  4. Ajouter un paramètre de contexte avec le nom de l' javax.faces.FACELETS_BUFFER_SIZE et une valeur de la Facelets réponse de la taille de la mémoire tampon en octets (par exemple, 65535 pour 64 KO), de sorte que l'ensemble de la sortie HTML, ou au moins de la <h:form> (voir #3) s'inscrit dans le tampon de réponse. Avantage/inconvénient, voir #3.

  5. Ajouter un paramètre de contexte avec le nom de l' javax.faces.STATE_SAVING_METHOD et la valeur de client de web.xml. Avantage: session ne sera pas créé à tous, sauf si vous avez de la session de l'étendue des haricots. Elle aussi immédiatement résout les éventuels ViewExpiredException des cas. Inconvénient: l'augmentation de la bande passante du réseau. Si vous êtes à l'aide partielle de l'etat l'épargne, l'impact devrait toutefois être minime.

Pourquoi le problème disparaît lorsque vous retirez <h:form>, c'est parce que pas de session doit être créé afin de stocker l'état d'affichage.


Mise à jour: c'est que par la double question 2277 été corrigés depuis Mojarra 2.1.8. Donc, vous pouvez également mettre à niveau au moins cette version.

6voto

Gaspar Kuhnen Points 41

Avec la nouvelle version 2.1.21 publiée hier de javax.faces, ce problème semble avoir disparu. Déclarez la nouvelle version:

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

et remplacez javax.faces.jar dans le dossier des modules de glassfish, en remplacement de javax.faces.jar pour la nouvelle version 2.1.21.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X