2012-06-08 8 views
7

sto ottenendo il seguente errore sulla mia applicazione pagina di avvio di carico:non possono creare la sessione dopo la risposta è stata impegnata

SEVERE: Error Rendering View[/HomeTemplate/equityVolume.xhtml] 
javax.el.ELException: /HomeTemplate/equityVolume.xhtml @70,78 value="#{equityBean.scripList}": java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed... 

    Caused by: java.lang.IllegalStateException: PWC3999: Cannot create a session after the response has been committed... 

ottengo questo errore quando applico il css alla mia homepage, l'errore scompare quando rimuovo il modello CSS (ma voglio aplly template css) seguito è riportato il codice del bean frammento di che causa l'errore (trovata da debug)

public List<MasterScrip> getScripList() { 
    HttpServletRequest req=(HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest(); //error line 
    HttpSession session=req.getSession(); 
    type=(String)session.getAttribute("type");... 

codice XHTML:

<h:body> 
    <ui:composition template="commonClientLayout.xhtml"> 

    <ui:define name="contentFile"> 
      <div id="content"> 
    <h:form id="frm">... 

quando rimuovo l'interfaccia utente: composizione e definire i tag (ad es. se non applico il css), allora non ottengo questo errore. cosa potrebbe causare questo errore e come lo risolvo?

Modificato:

@PostConstruct 
void initialiseSession() { 
    if(type!=null) 
     { 
     if(type.equalsIgnoreCase("losers")) 
     { 
     scripList=new ArrayList<MasterScrip>(); 
     scripList=getScripByPriceLosers(exchange); 
     // return scripList; 
     } 
     else if(type.equalsIgnoreCase("gainers")) 
     { 
     scripList=new ArrayList<MasterScrip>(); 
    scripList=getScripByPriceGainers(exchange); 
     // return scripList; 
     } 
     else 
     { 
      scripList=new ArrayList<MasterScrip>(); 
    scripList=getScripByVolumeType(exchange); 
    // return scripList; 
     } 
     } 
     else 
     { 
      scripList=new ArrayList<MasterScrip>(); 
    scripList=getScripByVolumeType(exchange); 
     } 

} 

    public List<MasterScrip> getScripList() { 
     return scripList; 

    } 

modificati di nuovo:

SEVERE: Error Rendering View[/equityVolume.xhtml] 
java.lang.IllegalStateException 
    at org.apache.catalina.connector.ResponseFacade.setBufferSize(ResponseFacade.java:275)... 

edit: web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
    <context-param> 
     <param-name>javax.faces.PROJECT_STAGE</param-name> 
     <param-value>Production</param-value> 
    </context-param> 
    <context-param> 
     <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name> 
     <param-value>65535</param-value> 
    </context-param> 

    <servlet> 
     <servlet-name>Faces Servlet</servlet-name> 
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>Faces Servlet</servlet-name> 
     <url-pattern>*.xhtml</url-pattern> 
    </servlet-mapping> 
    <session-config> 
     <session-timeout> 
      30 
     </session-timeout> 

    </session-config> 
    <welcome-file-list> 
     <welcome-file>equityVolume.xhtml</welcome-file> 
    </welcome-file-list> 
    <security-constraint> 
     <display-name>Constraint1</display-name> 
     <web-resource-collection> 
      <web-resource-name>AdminTemplate</web-resource-name> 
      <description/> 
      <url-pattern>/AdminTemplate/*</url-pattern> 
     </web-resource-collection> 
     <auth-constraint> 
      <description/> 
      <role-name>admin</role-name> 
     </auth-constraint> 
    </security-constraint> 
    <security-constraint> 
     <display-name>Constraint2</display-name> 
     <web-resource-collection> 
      <web-resource-name>ClientTemplate</web-resource-name> 
      <description/> 
      <url-pattern>/ClientTemplate/*</url-pattern> 
     </web-resource-collection> 
     <auth-constraint> 
      <description/> 
      <role-name>client</role-name> 
     </auth-constraint> 
    </security-constraint> 
    <login-config> 
     <auth-method>FORM</auth-method> 
     <realm-name>DataRealm</realm-name> 
     <form-login-config> 
      <form-login-page>/equityVolume.xhtml</form-login-page> 
      <form-error-page>/errorpage.xhtml</form-error-page> 
     </form-login-config> 
    </login-config> 
    <security-role> 
     <description/> 
     <role-name>admin</role-name> 
    </security-role> 
    <security-role> 
     <description/> 
     <role-name>client</role-name> 
    </security-role> 
</web-app> 

risposta

6

Non si dovrebbe fare un lavoro d'affari in getter. Fallo invece nel costruttore di bean (post).

vostro problema concreto è causato perché si sta richiedendo una pagina relativamente grande su una nuova sessione del browser fresco per cui il server HttpSession non è stato ancora creato e l'espressione EL #{equityBean.scripList} è fatto riferimento relativamente tardi nella pagina.

Il buffer di risposta è di 2KB difetto e quando trabocca causa di una grande risposta, allora sarà impegnato. Ciò significa che tutte le intestazioni di risposta saranno inviate e che verranno inviati prima i ~ 2 KB dell'output HTML. Quindi, dopo questo punto, l'espressione EL #{equityBean.scripList} verrà risolta in cui si sta tentando di ottenere la sessione. Se il server HttpSession non è stato ancora creato in quel momento, il server ha bisogno per impostare un cookie nell'intestazione di risposta al fine di mantenere per le richieste successive. Ma ovviamente non è possibile se la risposta è già stata commessa. Quindi questa eccezione.

Come detto, basta fare il lavoro nel costruttore del bean (post), invece. O semplicemente iniettalo come proprietà gestita.

@ManagedProperty("#{type}") 
private String type; 

Se si verifica ancora l'eccezione, probabilmente stai usando una vecchia versione di Mojarra, che soffre il bug come descritto nelle questioni 2215 e 2277 che è causato da troppo estrema rinvio della sessione "inutile" creazione. Questo problema è stato risolto da Mojarra 2.1.8. Quindi, l'aggiornamento ad esso o più recente (è attualmente 2.1.9) dovrebbe farlo.


non collegato al problema concreto, la logica getScripList() è dal modo maleodorante. Ma è soggetto a un altro problema/domanda. Sei consapevole che puoi semplicemente accedere all'attributo di sessione con il nome "tipo" in EL come #{type}? Sei consapevole che avere prime javax.servlet.* importazioni in una classe bean JSF supporto più spesso indicare che si sta forse facendo le cose nel modo sbagliato e che ci possono essere più "JSF-ish" modi per raggiungere il requisito funzionale di cemento?

+0

Grazie per la spiegazione. Ho impostato la logica di business nel metodo postConstruct, ancora ottengo lo stesso errore (vedi la domanda modificato). i cant ottenere qualsiasi ulteriore nella mia app, cosa devo fare? :( – z22

+0

Così il fagiolo non è semplicemente fatto riferimento in precedenza da nessuna parte con la pagina? Cosa JSF impl/versione stai usando? Un problema simile è stato risolto in Mojarra 2.1.8. In alternativa è possibile modificare e aumentare la dimensione del buffer di risposta di default – BalusC

+0

sì si fa riferimento in precedenza nella pagina xhtml – z22

3

Non conosco questo framework web (è JSF?) Ma ecco cosa succede. Il tuo XHTML inizia a mostrare l'output e alcuni caratteri sono già stati inviati al browser. Ciò implica che è stato inviato anche l'intero header.

qualche parte nel mezzo del vostro modello che si sta chiamando #{equityBean.scripList} (BTW errore di battitura) che a sua volta le chiamate:

HttpSession session=req.getSession(); 

Questo metodo creerà sessione HTTP se uno non esiste. L'ID di sessione deve essere inviato con risposta (utilizzando cookie o riscrittura degli URL) al client per identificare la sessione in base alle richieste successive. Tuttavia, poiché le intestazioni di risposta sono già state inviate, il contenitore di servlet non è in grado di inviare indietro l'ID di sessione e genera un'eccezione che evita problemi ancora più grandi.

Come si può risolvere questo? Sembra che tu stia rendendo la pagina per la prima volta quando non c'è assolutamente nessuna sessione associata alla richiesta. È possibile evitare la creazione della sessione:

HttpSession session=req.getSession(false); //false here! 
if(session != null) { 
    type=(String)session.getAttribute("type"); 
} 
//handle the case when session or type attribute weren't there 

Un altro approccio è quello di creare in modo proattivo la sessione prima di passare il controllo alla vista. Tuttavia, è ancora necessario controllare l'attributo type per null.

+0

provato, ancora ottengo l'errore ... i cant applico il css :( – z22

Problemi correlati