2012-08-01 27 views
5

I tienen las siguientes define en web.xml:página de error definido en web.xml está incrustado en la página JSF parcialmente generado

<error-page> 
    <exception-type>java.lang.Throwable</exception-type> 
    <location>/shared/errors/DefaultErrorPage.xhtml</location> 
</error-page> 
<error-page> 
    <exception-type>javax.faces.application.ViewExpiredException</exception-type> 
    <location>/shared/errors/ViewExpired.xhtml</location> 
</error-page> 

También estoy usando el FullAjaxExceptionHandler de Omnifaces en faces-config.xml:

<factory> 
    <exception-handler-factory> 
     org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory 
    </exception-handler-factory> 
</factory> 

el FullAjaxExceptionHandler está trabajando muy bien para las llamadas ajax, pero cuando llegué a una página directamente y no hay un error, se inicia la prestación de la página que estaba tratando de ir, pero no termina, y luego la página de error definida en web.xml se procesa, lo que da como resultado que se incorpore la página de error d después de una página parcialmente renderizada.

(estoy usando GlassFish 3.1.1 que tiene Mojarra JSF 2.1.3) Editar: ahora usando Glassfish 3.1.2.2 y 2.1.11 JSF

Editar: Descubierto el siguiente: la página en el error Está sucediendo el uso de plantillas (<ui:composition template="/shared/shared/commonLayout.xhtml">) Si lo cambio para que la página ya no use la plantilla, y luego simplemente agregue todo el código de la plantilla, entonces funciona bien.

+0

Esto es extraño. Para excluir el uno y el otro, ¿la etapa del proyecto JSF está configurada en 'Desarrollo' o no? – BalusC

+0

Sí, está establecido en Desarrollo. – jc12

+0

Traté de cambiarlo a Producción, pero sigo obteniendo los mismos resultados. No estoy seguro de lo que quiere decir con "excluir el uno y el otro".Si estoy usando FullAjaxExceptionHandlerFactory para llamadas ajax, ¿también necesito un ExceptionHandlerFactory para llamadas que no sean ajax? – jc12

Respuesta

5

Esto sucederá cuando la respuesta ya esté confirmada antes de que se produzca la excepción. La respuesta se confirmará cuando ServletOutputStream#flush() tenga una profundidad bajo las cubiertas JSF explícitamente invocada de alguna manera, que es más que a menudo solo cuando el buffer de respuesta (por defecto suele ser de 2 KB en la mayoría de los contenedores) se ha desbordado. Una respuesta comprometida es un punto sin retorno. El servidor no puede recuperar los bytes ya enviados del cliente. El servidor tiene básicamente 2 opciones:

  • Deje la respuesta tal como está y registre la excepción únicamente en el registro del servidor.
  • De todos modos, intente escribir la página de error en la respuesta.

Su configuración Glassfish aparentemente elige la 2 ª manera. Ninguno de ellos es perfecto. El cliente aún terminaría con una respuesta de HTML medio horneado y lo que sea que termine pareciéndose al usuario final depende de cómo el navegador web puede hacer todo lo posible para interpretar y presentar el HTML obtenido hasta ahora.

Usted, como desarrollador JSF, sin embargo puede utilizar varios enfoques para evitar que ocurra esto. En primer lugar, ¿por qué exactamente se ha lanzado esa excepción durante dando la respuesta? ¿Eso no indica un error en tu propio código? ¿No sería mejor realizar el trabajo comercial sensible a excepciones antes de representar la respuesta? Puede usar entre otros <f:event type="preRenderView"> para esto.

<f:event type="preRenderView" listener="#{bean.init}" /> 

Si eso no es realmente una opción, por alguna razón, usted podría considerar incrementar el tamaño de la memoria de respuesta a por encima del tamaño del mayor respuesta HTML, por lo que la respuesta no se auto-vaciado antes la excepción ocurre Puede hacerlo mediante el siguiente parámetro de contexto que asume que cada respuesta HTML se ajusta dentro del límite de 100 KB:

<context-param> 
    <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name> 
    <param-value>102400</param-value><!-- 100KB --> 
</context-param> 
+0

Aumentando el tamaño del búfer trabajado, gracias! El error se produce durante un PostConstruct en un ManagedBean. Hay muchos beans gestionados que se utilizan en la página, y la mayoría de ellos tienen su propio código de configuración en un método con una anotación PostConstruct. Para usar preRenderView, tendría que poner todo el código de inicio en una sola función, o tal vez puede tener múltiples eventos preRenderView, pero luego tendría que mantener los eventos para cada página. – jc12

Cuestiones relacionadas