2012-03-23 59 views
1

我在@ViewScoped mananged bean上有一个init方法。在后构造我加载数据从数据库。我有一个自定义ExceptionHandlerWrapper来捕获所有附加信息并发送到错误页面。然而,当@PostConstuct抛出一个异常,我收到一个IllegalStateException,并没有重定向到错误页面。我已经尝试了多种组合.....在@PostConstruct中引发的异常在JSF 2.1中导致IllegalStateException

我用尽我这ExcpetionHandler

externalContext.getRequestMap().put(ERROR_BEAN_ID, ERROR_TEXT); 
externalContext.dispatch(ERROR_PAGE); 
fc.responseComplete(); 

内部下面这行是什么原本我。它还doent工作

externalContext.getFlash().put(ERROR_BEAN_ID, ERROR_TEXT); 
nav.handleNavigation(fc, null, ERROR_PAGE); 
fc.renderResponse(); 

这些都导致IllegalStateExceptions。我也叫同样的结果重定向。

您可以全局捕获@PostConstruct引发的错误吗?

回答

3

这些都会导致IllegalStateException异常。

消息 “回应已经承诺”,我认为?那么,这是一个不归路。部分响应已经发送给客户端(网页浏览器)。无法将已发送的字节送回。服务器最终会在日志中发生这种异常,客户端将以半响应结束。

你能做什么?

最直接的方法是将响应缓冲区大小放大到最大页面的大小。例如,64KB:

<context-param> 
    <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name> 
    <param-value>65536</param-value> 
</context-param> 

根据服务器配置,它默认为〜2KB。你只需要记住,当你的服务器需要处理相当多的请求/响应时,这可能会导致内存耗尽。配置文件并正确测量。

另一种方式是之前引用豆的响应被渲染/犯下如此,它的(岗位)建设点之前触发。也许有问题的bean是第一次在视图底部引用,远远超出〜2KB响应大小的边界。您可以接管@PostConstruct的工作,并在视图顶部的某个地方使用<f:event type="preRenderView">。例如。

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

public void init() { 
    if (!FacesContext.getCurrentInstance().isPostback()) { 
     // Do here your original @PostConstruct job. 
    } 
} 
+0

谢谢。是的“响应已经提交”是错误取决于我是否使用重定向/调度。我刚刚删除了preRenderView的使用,因为我动态配置了来自db和f:validateBean等的元数据的页面,并且f:标记在调用preRenderView之前被初始化。从而导致页面验证无法正常工作。所以如果我需要预先加载的数据,将配置视图和全局异常处理我坚持与缓冲区解决方案? – user1147953 2012-03-24 02:15:45