2011-11-09 12 views
46

sto affrontando la seguente eccezione in modo molto semplice pagina JSF 2 dopo aver aggiunto <h:form>:Aggiunta <h:form> cause java.lang.IllegalStateException: Impossibile creare una sessione dopo la risposta è stata impegnata

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) 

Sono utilizzando Mojarra 2.1.3 e PrimeFaces3.0M4, su Tomcat 7.0.22 e JDK 7.

La pagina è una tabella di dati molto semplice:

<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 pagina mostra correttamente sul browser, ma sulla console vedo l'eccezione. L'eccezione scompare se rimuovo lo <h:form>.

Come è questo ha causato e come posso risolverlo?

risposta

82

Questo è un problema noto e stato segnalato dal sottoscritto come issue 2215. Ciò si verifica quando il buffer di risposta ha overflow (a causa di contenuti di grandi dimensioni) e la risposta è stata confermata prima che la sessione sia stata creata. Questo è il risultato di alcuni tentativi eccessivamente zelanti di Mojarra di posticipare il più possibile la creazione di sessioni "non necessarie" (che è comunque una buona cosa).

Fino a quando non lo aggiusteremo, ci sono diverse soluzioni:

  1. Creare una Filter che fa HttpServletRequest#getSession() prima FilterChain#doFilter(). Vantaggio: non è necessario modificare la configurazione/codice JSF. Svantaggio: quando si desidera evitare anche la creazione di sessioni non necessarie.

  2. Chiama ExternalContext#getSession() con true nel gestore (post) del bean o nel listener preRenderView. Vantaggio: in realtà, niente. Svantaggio: troppo hacky.

  3. aggiungere un parametro di contesto con nome com.sun.faces.writeStateAtFormEnd e il valore di false-web.xml. Vantaggio: la creazione di sessioni non necessarie sarà davvero evitata rispetto a # 1 e # 2. Svantaggio: la risposta verrà ora completamente memorizzata nella memoria fino al raggiungimento di </h:form>. Se le tue forme non sono estremamente grandi, l'impatto dovrebbe comunque essere minimo. Tuttavia, fallirebbe comunque se il tuo <h:form> si avvia relativamente tardi nella vista. Questo può essere combinato con # 4.

  4. Aggiungere un parametro di contesto con nome javax.faces.FACELETS_BUFFER_SIZE e un valore della risposta dimensione del buffer Facelets in byte (es 65535 per 64 KB) in modo che l'intero output HTML o almeno la <h:form> (vedi # 3) si inserisce nella risposta buffer. Vantaggio/svantaggio, vedi # 3.

  5. aggiungere un parametro di contesto con nome javax.faces.STATE_SAVING_METHOD e il valore di client-web.xml. Vantaggio: la sessione non verrà creata a meno che non si disponga di bean con scope di sessione. Risolve immediatamente anche i potenziali casi ViewExpiredException. Svantaggio: maggiore utilizzo della larghezza di banda della rete. Se stai utilizzando il salvataggio parziale dello stato, l'impatto dovrebbe comunque essere minimo.

Quanto al motivo per il problema scompare quando si rimuove <h:form>, questo è perché nessuna sessione deve essere creato al fine di conservare lo stato di visualizzazione.


Aggiornamento: questo ha come per il duplicato issue 2277 stati corretti dal Mojarra 2.1.8. Quindi, puoi anche solo aggiornare ad almeno quella versione.

+1

grazie! sembra che questo problema verrà risolto con Mojarra 2.1.8 (http://java.net/jira/browse/JAVASERVERFACES-2277) che dovrebbe essere rilasciato a breve – wemu

+1

Leggere l'intero JIRA sembra che il problema sia ancora in giro , 2.1.16 –

+0

Ho avuto un problema simile, e mentre sto usando 2.1.13, il problema era intorno. L'implementazione del consiglio n. 3, tuttavia, lo risolse. –

5

Con la nuova versione 2.1.21 rilasciata ieri di javax.faces questo problema sembra essere scomparso. Dichiarare la nuova versione:

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

e sostituire il javax.faces.jar nella cartella moduli pesci vetro sostituzione del javax.faces.jar per la nuova versione 2.1.21.

-1

Se si utilizza Spring MVC e la chiamata viene eseguita da Spring Forms, è necessario utilizzare il metodo GET anziché il POST (per recuperare i dati) e non ci dovrebbero essere campi di input che possiamo utilizzare intead.

+0

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

2

Nel mio caso (myfaces-2.2.8 & Tomcat 8.0.23) il Problema era un refuso nello welcome-file di web.xml. Durante il debug ho visto che Tomcat ha creato come previsto un 404, ma in qualche modo i myfaces hanno provato ad accedere successivamente alla Session, che ha causato quindi un java.lang.IllegalStateException: Cannot create a session after the response has been committed. L'utilizzo di una pagina valida in welcome-file di web.xml ha risolto il problema per me.

0

Potrebbe essere necessario aggiungere un <f:view> e </f:view> prima e dopo h:form elementi, oltre a aggiungere il collegamento a voi tag HTML per i tag JSF

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

per questo lavoro.

Problemi correlati