<partial-response>
<error>
<error-name>...</error-name>
<error-message>...</error-message>
</error>
</partial-response>
可参见com.sun.faces.context.AjaxExceptionHandlerImpl的源码。
一、使用JS函数处理Ajax异常
JSF提供了全局脚本函数addOnError()用于监控Ajax错误,将函数定义在全局模板内可以实现页面共用。
全局函数定义在jsf.ajax.js文件中,使用全局函数的页面应引用该脚本资源文件:
<h:head>
<h:outputScript library="javax.faces" name="jsf.js"/>
</h:head>
定义全局回调函数:
<h:head>
<h:outputScript>
var handleError = function(data){
var componentId = data.source.id;
var xml = data.responseXML;
var text = data.responseText;
var code = data.responseCode;
var type = data.type;
var status = data.status;
var description = data.description;
var errorName = data.errorName;
var errorMessage = data.errorMessage;
var error = ... + ... + ....;
alert(error);
location.href = "/welcome.xhtml";
}; jsf.ajax.addOnError(handleError);
</h:outputScript>
</h:head> 二、利用OmniFaces OmniFaces是一个 JSF 2 的工具库,其中定义了Ajax异常处理类 FullAjaxExceptionHandler,能够自动处理异常,使用方式与普通JSF异常一样,利用web.xml error-page机制。
在pom中引入omnifaces:
<dependency>
<groupId>org.omnifaces</groupId>
<artifactId>omnifaces</artifactId>
<version>1.6.3</version>
</dependency> 在
faces-config.xml
中注册handler:<factory>
<exception-handler-factory>
org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory
</exception-handler-factory>
</factory>
在web.xml中定义error-page:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/WEB-INF/errorpages/expired.xhtml</location>
</error-page>
<error-page>
<exception-type>java.sql.SQLException</exception-type>
<location>/WEB-INF/errorpages/database.xhtml</location>
</error-page>
<error-page>
<exception-type>java.lang.RuntimeException</exception-type>
<location>/WEB-INF/errorpages/bug.xhtml</location>
</error-page>
errorpage.xhtml:
<ui:composition template="/WEB-INF/templates/layout.xhtml"
xmlns=" http://www.w3.org/1999/xhtml"
xmlns:h=" http://java.sun.com/jsf/html"
xmlns:ui=" http://java.sun.com/jsf/facelets"
xmlns:fn=" http://java.sun.com/jsp/jstl/functions"
xmlns:of=" http://omnifaces.org/functions">
<ui:define name="contentTitle">Error</ui:define> <ui:define name="content">
<ui:insert name="errorContent">
<ul>
<li>Date/time: #{of:formatDate(now, 'yyyy-MM-dd HH:mm:ss')}</li>
<li>User agent: #{header['user-agent']}</li>
<li>User IP: #{empty header['x-forwarded-for'] ? request.remoteAddr : fn:split(header['x-forwarded-for'], ',')[0]}</li>
<li>Request URI: <a href="#{requestScope['javax.servlet.error.request_uri']}">#{requestScope['javax.servlet.error.request_uri']}</a></li>
<li>Ajax request: #{facesContext.partialViewContext.ajaxRequest ? 'Yes' : 'No'}</li>
<li>Status code: #{requestScope['javax.servlet.error.status_code']}</li>
<li>Exception type: #{requestScope['javax.servlet.error.exception_type']}</li>
<li>Exception message: #{requestScope['javax.servlet.error.message']}</li>
<li>Stack trace: <pre><code>#{of:printStackTrace(requestScope['javax.servlet.error.exception'])}</code></pre></li>
</ul>
</ui:insert>
<h:outputScript rendered="#{facesContext.partialViewContext.ajaxRequest}">scrollTo(0, 0);</h:outputScript>
</ui:define>
</ui:composition>