- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我为 JSF 编写了一个自定义异常处理程序来记录异常并导航到要向用户显示的错误页面。不幸的是,在 Handler 中调用“handleNavigation”时,我收到 IllegalStateException“无法在提交响应后调用 sendRedirect()”。任何想法,我做错了什么?
我的处理程序:
public class MyExceptionHandler extends ExceptionHandlerWrapper {
private Logger log = ...;
public ExceptionHandler wrappedHandler = null;
public MyExceptionHandler (ExceptionHandler wrappedHandler) {
this.wrappedHandler = wrappedHandler;
}
@Override
public ExceptionHandler getWrapped() {
return wrappedHandler;
}
@Override
public void handle() throws FacesException {
Iterator<ExceptionQueuedEvent> iter = null;
ExceptionQueuedEvent event = null;
ExceptionQueuedEventContext eventContext = null;
FacesContext facesContext = null;
iter = getUnhandledExceptionQueuedEvents().iterator();
while (iter.hasNext()) {
try {
event = iter.next();
eventContext = (ExceptionQueuedEventContext) event.getSource();
log.error("JSF Exception aufgetreten", eventContext.getException());
facesContext = FacesContext.getCurrentInstance();
// !!!!!!!! Exception occurs here !!!!!!!!!!!
facesContext
.getApplication()
.getNavigationHandler()
.handleNavigation(facesContext, null, "error");
facesContext.renderResponse();
} catch (RuntimeException ex) {
throw ex; // just to set break point
} finally {
iter.remove();
}
}
getWrapped().handle();
}
}
faces-config.xml 中的导航定义
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<from-outcome>error</from-outcome>
<to-view-id>/faces/error.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
最佳答案
正在处理的异常显然是在渲染响应阶段抛出的,此时 HTTP 响应已经提交。提交的响应意味着 HTTP 响应的第一部分(包括 header )已经发送到客户端。这是一条不归路。您无法从客户端取回已发送的字节。
当写入的内容超过缓冲区大小时,通常会自动提交响应,缓冲区大小通常默认为 ~2KB,具体取决于 servletcontainer 和 Facelets 配置。平均 HTML <head>
已经占用1~2KB。所以变化很大,在 JSF 开始呈现 <body>
之前已经提交了响应。或者只是其中的一小部分。
在您的特定情况下还有一个原因:当您收到不止一个未处理的异常时,您也会遇到麻烦,因为您没有中止 while
导航后循环,但继续处理下一个异常。您不能对单个请求返回多个响应(错误页面)。您应该收集所有异常并仅导航一次,或者在第一个异常之后中止循环。
在任何情况下,处理渲染响应期间抛出的异常只有在响应未(自动)提交时才有可能。您可以尝试多种方法来防止响应过早自动提交:
将 Facelets 缓冲区大小设置为最大 HTML 响应的大小。例如。 64KB:
<context-param>
<param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
<param-value>65535</param-value><!-- 64KB -->
</context-param>
在呈现 View 之前执行异常敏感的业务作业(即不要在 GET 请求期间构造的 bean 的(后)构造函数中执行此操作):
<f:event type="preRenderView" listener="#{bean.init}" />
关于一般 JSF 中的异常处理,您可能会发现 OmniFaces FullAjaxExceptionHandler
有帮助。你可以找到它的源代码 here .
关于JSF 2.0 自定义异常处理程序在 handleNavigation 上抛出 IllegalStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15610974/
我正在使用 JSF2.0 Mojarra 2.0.2。 我有一种方法可以注销用户并将注销消息放入 flash,然后转发到登录页面(其中有一个打印出 flash 的 div)。但是,当我出于某种原因使用
我有一个 PhaseListener 来控制用户对某些页面的访问,如果用户未登录,他将被重定向到登录页面。 问题是我的方法handleNavigation没有重定向用户。它运行但不会重定向用户。 当用
在“RESTORE_VIEW”阶段运行的阶段监听器类中,我有一些这样的代码: public void afterPhase(PhaseEvent event) { FacesContext fc
以下内容似乎是等效的: FacesContext.getCurrentInstance().getApplication().getNavigationHandler().handleNavigati
我为 JSF 编写了一个自定义异常处理程序来记录异常并导航到要向用户显示的错误页面。不幸的是,在 Handler 中调用“handleNavigation”时,我收到 IllegalStateExce
我是一名优秀的程序员,十分优秀!