欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JSF中Exception的处理

程序员文章站 2022-07-15 19:34:05
...

JSFException的处理<o:p></o:p>

环境: myfaces1.1.5,richfaces1.3,Websphere6.1

目标

统一处理应用中的Exception,解析其中的错误信息,使用Globalization 来显示消息。

分析

JSF中有两类error,一类是input error,是由用户输入错误的信息造成的,一般在input 验证或者转化过程中会出现;另一类是application error,是系统中可能出现的各种错误,如SQLExceptionNullPointerException等。对于application error,在系统中会统一抛出AppException,然后由我们自己订制的ActionListener处理;而对于input error,则由JSF处理。下面详细讨论如何处理application Error.

思路:将Exception转化为Faces Message处理。

在系统中我们采用两种策略共同处理Exception。即当JSF请求处理中出现Exception时,采取第一种策略,在这个页面上显示一条消息提示用户;当非JSF请求出现Exception时,将这个Exception抛给Web Container,并将页面导航到某一个错误页面。。

<o:p> </o:p>

实现<o:p></o:p>

下面分别讨论这两种策略如何实现。<o:p></o:p>

第一种,JSF请求,弹出提示消息。<o:p></o:p>

在我们的系统中,综合使用Exception FacesMessage来综合处理Exception,当Exception抛出时,尤其是Business Exception发生时,这个Exception是发生在JSFInvokeAppication Phase,因此通过订制ActionListener就捕获这个Exception,并将这个Exception转化为FacesMessage,并根据ExceptionMessage到资源文件中加载对应的国际化。

ActionListen无法捕获这个Exception时,将这个错误发送到WebContainer,并转向error页面。这时,对于这个请求的响应会产生500Error Code并发送到客户端。

因此,首先要定制JSFActionListener,在其上添加以下方法:<o:p></o:p>

try {<o:p></o:p>

outcome = (String) methodBinding.invoke(facesContext, null);<o:p></o:p>

} catch (Exception e) {<o:p></o:p>

Throwable cause = e.getCause();<o:p></o:p>

if (cause != null && cause instanceof AbortProcessingException) {<o:p></o:p>

throw (AbortProcessingException) cause;<o:p></o:p>

} else {<o:p></o:p>

Exception ex = (Exception) e.getCause();<o:p></o:p>

String message = ex.getMessage();<o:p></o:p>

//get localized Message string from resource bundle <o:p></o:p>

String localizedMessage = getBundleMessage(message);<o:p></o:p>

if (null != localizedMessage && "".equals(localizedMessage)) {<o:p></o:p>

throwNewFacesMessage(actionEvent.getComponent()<o:p></o:p>

.getClientId(facesContext), localizedMessage,<o:p></o:p>

FacesMessage.SEVERITY_ERROR);<o:p></o:p>

} else {<o:p></o:p>

throwNewFacesMessage(actionEvent.getComponent()<o:p></o:p>

.getClientId(facesContext), message,<o:p></o:p>

FacesMessage.SEVERITY_ERROR);<o:p></o:p>

}<o:p></o:p>

}// org.apache.myfaces.application.ActionListenerImpl

在上面的方法中拦截所有的Exception,并转化为FacesMessage,这样JSF会直接转向Render Phase,从而停止Application method的进一步处理,实现Exceptionhandler<o:p></o:p>

其次,在页面上添加<h:messages></h:messages>标识,就可以显示所有的错误消息。<o:p></o:p>

再者,覆盖A4J.AJAX.onError由于我们在系统中还采用了RichfacesRichfaces在判断Ajax请求在服务器的处理出现错误后,会有一个默认的处理函数A4J.AJAX.onError这样当服务器端发送500Error Code时,就可以被客户端的Ajax感知,并添加处理:<o:p></o:p>

A4J.AJAX.onError = function(req,status,message) {

var report = "An error has occurred during the request,Message is: " + message;

if(Ext.MessageBox.show){

Ext.MessageBox.show({

title: 'Error Report',

msg: report,

width:400,

buttons: Ext.MessageBox.OK

});

}else{

alert(report);

}

<o:p> </o:p>

};<o:p></o:p>

第二种,非Ajax请求,跳转到错误页面。可以通过配置web.xml来实现:<o:p></o:p>

<error-page>

<exception-type>javax.faces.FacesException<!---->exception-type>

<location>/error.jsp<!---->location>

<!---->error-page>

<error-page>

<error-code>500<!---->error-code>

<location>/error.jsp<!---->location>

<!---->error-page><o:p></o:p>

这样,当产生错误时,就会转向这个页面。<o:p></o:p>