2012-06-08 13 views
7

begangen wurde ich auf meinem Start der Anwendung Laden der Seite die folgende Störung erhalte:Sitzung nicht erstellt werden kann, nachdem Reaktion hat

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

ich diese Fehlermeldung erhalten, wenn ich die CSS auf meine Homepage anwenden, verschwindet der Fehler, wenn ich entfernen die CSS-Vorlage (aber ich will die CSS-Vorlage aplly) finden Sie die Bean-Code-snippet, das den Fehler verursacht

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

xHTML-Code (durch Debugging gefunden):

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

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

wenn ich die ui: Zusammensetzung lösche und Tags definiere (d. H. Wenn ich das CSS nicht anwende, dann bekomme ich diesen Fehler nicht. Was könnte diesen Fehler verursachen und wie löse ich ihn?

bearbeitet:

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

    } 

bearbeitet wieder:

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> 

Antwort

6

Sie sollten nicht in Getter Business-Job machen. Tun Sie es stattdessen im Bean (Post) -Konstruktor.

Ihr konkretes Problem wird verursacht, weil Sie in einer neuen Browsersitzung eine relativ große Seite anfordern, für die der Server HttpSession noch nicht erstellt wurde und der EL-Ausdruck #{equityBean.scripList} relativ spät auf der Seite referenziert wird.

Der Antwortpuffer ist standardmäßig 2 KB und wenn er wegen einer großen Antwort überläuft, wird er festgeschrieben. Dies bedeutet, dass alle Antwortheader gesendet werden und die ersten ~ 2 KB der HTML-Ausgabe gesendet werden. Nach diesem Punkt wird der EL-Ausdruck #{equityBean.scripList} aufgelöst, in dem Sie versuchen, die Sitzung zu erhalten. Wenn der Server HttpSession zu diesem Zeitpunkt noch nicht erstellt wurde, muss der Server verwenden, um im Antwortheader einen Cookie zu setzen, damit er für nachfolgende Anforderungen gepflegt wird. Das ist natürlich nicht möglich, wenn die Antwort bereits erfolgt ist. Daher diese Ausnahme.

Wie gesagt, machen Sie stattdessen den Job in Bean (Post) Konstruktor. Oder injiziere es einfach als Managed Property.

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

Wenn die Ausnahme auftritt, sind Sie wahrscheinlich eine ältere Version von Mojarra verwendet, die vom Bug leidet wie 2215 und 2277 in Fragen beschrieben, die durch zu extremer Aufschiebung der „unnötigen“ Sitzung verursacht wird Schaffung. Dies wurde seit Mojarra 2.1.8 behoben. Ein Upgrade auf dieses oder ein neueres System (derzeit 2.1.9) sollte dies tun.


Unrelated auf das konkrete Problem, die getScripList() Logik ist übrigens muffig. Aber das ist Thema für ein anderes Problem/eine andere Frage. Ist Ihnen bewusst, dass Sie einfach auf das Sitzungsattribut mit dem Namen "type" in EL als #{type} zugreifen können? Ist Ihnen bewusst, dass der Import von rohen javax.servlet.* -Importen in eine JSF-Backing-Klasse mehr als oft anzeigt, dass Sie möglicherweise Dinge falsch machen und dass es möglicherweise mehr JSF-ish-Wege gibt, um die konkrete funktionale Anforderung zu erfüllen?

+0

danke für die Erklärung. Ich setze die Geschäftslogik in der PostConstruct-Methode, immer noch bekomme ich den gleichen Fehler (siehe die bearbeitete Frage). Ich kann nicht weiter in meiner App, was soll ich tun? :( – z22

+0

So die Bean ist einfach nicht irgendwo früher auf der Seite verwiesen? Welche JSF impl/Version verwenden Sie? Ein ähnliches Problem wurde in Mojarra 2.1.8 behoben. Alternativ können Sie die Standard-Antwortpuffergröße ändern und erhöhen – BalusC

+0

ja es wird früher auf der xhtml-Seite referenziert – z22

3

Ich kenne dieses Web-Framework nicht (ist es JSF?), Aber hier ist was passiert. Ihr XHTML beginnt mit der Ausgabe der Ausgabe, und einige Zeichen wurden bereits an den Browser gesendet. Dies bedeutet, dass der gesamte Header ebenfalls gesendet wurde.

Irgendwo in der Mitte der Vorlage, die Sie anrufen #{equityBean.scripList} (BTW Typo), die in schaltet Anrufe:

HttpSession session=req.getSession(); 

Diese Methode wird HTTP-Sitzung erstellen, wenn man nicht existiert. Die Sitzungs-ID muss mit Antwort (mithilfe von Cookie oder URL-Umschreiben) zurück an den Client gesendet werden, um die Sitzung bei nachfolgenden Anforderungen zu identifizieren. Da jedoch die Antwortheader bereits gesendet wurden, kann der Servlet-Container die Sitzungs-ID nicht zurücksenden - und löst eine Ausnahme aus, die noch größere Probleme vermeidet.

Wie können Sie das lösen? Es sieht so aus, als würden Sie die Seite zum ersten Mal rendern, wenn der Anfrage absolut keine Sitzung zugeordnet ist. Sie können die Erstellung der Sitzung vermeiden:

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 

Ein weiterer Ansatz ist, um proaktiv die Sitzung zu erstellen, bevor Sie die Steuerung an die Ansicht übergeben. Sie müssen jedoch immer noch das type Attribut für null überprüfen.

+0

versuchte es, immer noch bekomme ich den Fehler ... ich kann nicht anwenden css :( – z22