我的@ViewScoped mananged bean上有一个init方法。在post构造中,我从db加载数据。我有一个自定义ExceptionHandlerWrapper来捕获所有的排除并发送到错误页面。但是当@PostConstuct抛出异常时,我收到IllegalStateException并且没有重定向到错误页面。我尝试了很多组合......
我在我的ExcpetionHandler
中尝试过这个externalContext.getRequestMap().put(ERROR_BEAN_ID, ERROR_TEXT);
externalContext.dispatch(ERROR_PAGE);
fc.responseComplete();
以下这一行是我原来的。它也很重要
externalContext.getFlash().put(ERROR_BEAN_ID, ERROR_TEXT);
nav.handleNavigation(fc, null, ERROR_PAGE);
fc.renderResponse();
这些都会导致IllegalStateExceptions。我也用相同的结果调用了重定向。
你可以全局捕获从@PostConstruct抛出的错误吗?
答案 0 :(得分:3)
这些都会导致IllegalStateExceptions。
有消息“响应已经提交”,我假设?嗯,这是一个不归路的点。响应的一部分已经发送到客户端(webbrowser)。无法取回已发送的字节。服务器将在日志中结束此异常,客户端将以半熟响应结束。
你能做什么?
最直接的方法是将响应缓冲区大小扩大到最大页面的大小。例如,64KB:
<context-param>
<param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
<param-value>65536</param-value>
</context-param>
默认为~2KB,具体取决于服务器配置。您只需要记住,当您的服务器必须处理相对大量的请求/响应时,这可能会占用内存。正确地描述和衡量。
另一种方法是在之前引用bean ,以呈现/提交响应,以便在该点之前触发(post)构造。也许有问题的bean第一次被引用到视图的最底部,远远超过~2KB的响应大小边界。您可以在视图顶部的某处@PostConstruct
接管<f:event type="preRenderView">
的工作。 E.g。
<f:event type="preRenderView" listener="#{bean.init}" />
与
public void init() {
if (!FacesContext.getCurrentInstance().isPostback()) {
// Do here your original @PostConstruct job.
}
}