我正在开发一个基于 JSF 2.0 的 Web 应用程序。我正在尝试实现一个全局异常处理程序,每当发生任何异常(例如 NullPointerException、ServletException、ViewExpiredException 等)时,该处理程序都会将用户重定向到通用错误页面
每当我的应用程序中发生 NPE 时,我的 customnavhandler 断点就会被命中并执行 NavigationHandler 代码,但不知何故没有重定向到错误页面,请求的页面仍然部分呈现。知道这里可能出了什么问题吗?一个信息是我故意在请求的页面上抛出一个 NPE(在 NPE 之后部分呈现)
我的 faces-config.xml 条目
<factory>
<exception-handler-factory>
com.common.exceptions.CustomExceptionHandlerFactory
</exception-handler-factory>
</factory>
我的自定义导航处理程序
public class CustomExceptionHandler extends ExceptionHandlerWrapper {
private static final Logger logger = Logger.getLogger("com.gbdreports.common.exception.CustomExceptionHandler");
private final ExceptionHandler wrapped;
public CustomExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public ExceptionHandler getWrapped() {
return this.wrapped;
}
public void handle() throws FacesException {
final Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
while (i.hasNext()) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context =
(ExceptionQueuedEventContext) event.getSource();
// get the exception from context
Throwable t = context.getException();
final FacesContext fc = FacesContext.getCurrentInstance();
final ExternalContext externalContext = fc.getExternalContext();
final Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
final ConfigurableNavigationHandler nav = (ConfigurableNavigationHandler) fc.getApplication().getNavigationHandler();
//here you do what ever you want with exception
try {
//log error ?
logger.error("Severe Exception Occured");
//log.log(Level.SEVERE, "Critical Exception!", t);
//redirect error page
requestMap.put("exceptionMessage", t.getMessage());
nav.performNavigation("/TestPRoject/error.xhtml");
fc.renderResponse();
// remove the comment below if you want to report the error in a jsf error message
//JsfUtil.addErrorMessage(t.getMessage());
}
finally {
//remove it from queue
i.remove(); }
}
//parent hanle
getWrapped().handle();
}
}
我的定制Navhandler工厂
public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
return new CustomExceptionHandler (parent.getExceptionHandler());
}
}
这很可能是因为当前请求是 ajax(异步)请求。您所拥有的异常处理程序是为常规(同步)请求而设计的。
发生ajax异常时更改视图的正确方法如下:
String viewId = "/error.xhtml";
ViewHandler viewHandler = context.getApplication().getViewHandler();
context.setViewRoot(viewHandler.createView(context, viewId));
context.getPartialViewContext().setRenderAll(true);
context.renderResponse();
然而,这有些天真。如果在渲染 ajax 响应期间抛出 ajax 异常,则此方法将不起作用。
我建议不要重新发明轮子。 JSF 实用程序库OmniFaces http://omnifaces.org有一个完整的工作解决方案FullAjaxExceptionHandler http://omnifaces.org/docs/javadoc/current/org/omnifaces/exceptionhandler/FullAjaxExceptionHandler.html。你可以找到完整的源代码here https://github.com/omnifaces/omnifaces/blob/master/src/main/java/org/omnifaces/exceptionhandler/FullAjaxExceptionHandler.java和展示示例here http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler。它使用标准 servlet API<error-page>
中的声明web.xml
。这样,错误页面也可以重用于同步请求,只需一点帮助FacesExceptionFilter
,也由 OmniFaces 提供。
也可以看看:
- 在 JSF 错误处理程序中使用ExternalContext.dispatch 会导致页面呈现损坏 https://stackoverflow.com/questions/15474345/using-externalcontext-dispatch-in-jsf-error-handler-causes-corrupt-page-renderin/
- 处理 AJAX 化组件的 JSF 2.0 异常的正确方法是什么? https://stackoverflow.com/questions/10449862/what-is-the-correct-way-to-deal-with-jsf-2-0-exceptions-for-ajaxified-components/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)