2012-06-08 28 views
7

que estoy recibiendo el siguiente error en mi solicitud de la página de inicio de carga:no se puede crear la sesión después de la respuesta se ha cometido

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

me sale este error cuando aplico el css a mi página, el error desaparece cuando quito la plantilla css (pero quiero aplly la plantilla css) siguiente es el fragmento de código de frijol que causa el error (que se encuentra por la depuración)

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

código XHTML:

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

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

cuando elimino la ui: composición y defino las etiquetas (es decir. si no aplico el css), entonces no consigo este error. ¿Qué podría estar causando este error y cómo lo resuelvo?

Editado:

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

    } 

nuevamente la edición:

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

edición: 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> 

Respuesta

6

No debería estar haciendo un trabajo de negocios en getters. Hazlo en el constructor bean (post) en su lugar.

Su problema concreto se debe a que está solicitando una página relativamente grande en una nueva sesión de navegador nueva para la que todavía no se ha creado el servidor HttpSession y la expresión EL #{equityBean.scripList} se hace referencia relativamente tarde en la página.

El búfer de respuesta es de forma predeterminada 2 KB y cuando se desborda debido a una gran respuesta, se confirmará. Esto significa que todos los encabezados de respuesta se enviarán y que primero se enviarán ~ 2 KB de la salida HTML. Luego, después de ese punto, se resolverá la expresión EL #{equityBean.scripList} en la que intentas obtener la sesión. Si el servidor HttpSession no se ha creado aún en ese momento, entonces el servidor necesita para establecer una cookie en el encabezado de respuesta a fin de mantenerla para solicitudes posteriores. Pero eso por supuesto no es posible si la respuesta ya se ha confirmado. De ahí esta excepción.

Como dije, simplemente haga el trabajo en el constructor de Bean (post) en su lugar. O simplemente inyéctelo como propiedad administrada.

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

Si se sigue produciendo la excepción, es probable que estés utilizando una versión anterior de Mojarra, que padece el error como se describe en cuestiones 2215 y 2277 que es causada por posponiendo demasiado extrema de la sesión de "innecesaria" creación. Esto se ha corregido desde Mojarra 2.1.8. Por lo tanto, actualizarlo o más nuevo (actualmente es 2.1.9) debería hacerlo.


Sin relación al problema concreto, la lógica getScripList() es por cierto mal olor. Pero eso está sujeto a un problema/pregunta diferente. ¿Sabe que puede acceder al atributo de sesión con el nombre "tipo" en EL como #{type}? ¿Sabe que tener importaciones de javax.servlet.* en bruto en una clase de bean de respaldo JSF indica con frecuencia que posiblemente esté haciendo las cosas mal y que puede haber más formas "JSF-ish" de lograr el requisito funcional concreto?

+0

gracias por la explicación. Configuré la lógica de negocio en el método postConstruct, aún obtengo el mismo error (vea la pregunta editada). No puedo avanzar más en mi aplicación, ¿qué debo hacer? :( – z22

+0

Por lo tanto, simplemente no se hace referencia al bean en ninguna parte anterior de la página. ¿Qué versión/versión de JSF está usando? Se corrigió un problema similar en Mojarra 2.1.8. Alternativamente, puede cambiar y aumentar el tamaño predeterminado del búfer de respuesta. – BalusC

+0

sí se hace referencia anteriormente en la página xhtml – z22

3

No conozco este framework web (¿es JSF?) Pero aquí está lo que sucede. Tu XHTML comienza a mostrar la salida y ya se han enviado algunos caracteres al navegador. Esto implica que también se envió el encabezado completo.

En algún lugar de la mitad de su plantilla que están llamando #{equityBean.scripList} (Por cierto error tipográfico) que a su vez las llamadas:

HttpSession session=req.getSession(); 

Este método creará sesión HTTP si no existe uno. La ID de la sesión debe enviarse con respuesta (utilizando cookies o reescritura de URL) de vuelta al cliente para identificar la sesión en las solicitudes posteriores. Sin embargo, dado que los encabezados de respuesta ya se enviaron, el contenedor de servlets no es capaz de devolver la Id. De sesión, y arroja una excepción que evita problemas aún mayores.

¿Cómo se puede resolver esto? Parece que estás renderizando la página por primera vez cuando no hay absolutamente ninguna sesión asociada con la solicitud. Puede evitar la creación de la sesión:

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 

Otro enfoque es crear de forma proactiva la sesión antes de pasar el control a la vista. Sin embargo, todavía debe verificar el atributo type para null.

+0

lo intenté, todavía me sale el error ... no puedo aplicar el css :( – z22

Cuestiones relacionadas