一个用于J2EE应用程序的异常处理框架(二)

2014-11-23 22:09:44 · 作者: · 浏览: 1
eption( "Exception occurred while using copy properties", se); }

  这里,CopyPropertiesException扩展了java.lang.RuntimeException,我们将会记录它。我们捕捉的是Exception,而不是copyProperties方法可以抛出的特定checked异常,因为对于所有这些异常来说,我们都会抛出同一个unchecked CopyPropertiesException异常。

过多异常

  您可能想知道,如果我们为每条错误消息创建一个异常,异常类自身是否会溢出呢?例如,如果“Order not found”是OrderNotFoundException的一条错误消息,您肯定不会让CustomerNotFoundException的错误消息为“Customer not found”,理由很明显:这两个异常代表同样的意义,惟一的区别在于使用它们的上下文不同。所以,如果可以在处理异常时指定上下文,我们无疑可以把这些异常合并为一个RecordNotFoundException。下面给出一个例子:

try{     ... }catch(BaseAppException ex){     IExceptionHandler eh =ExceptionHandlerFactory       .getInstance().create();     ExceptionDTO exDto = eh.handleException(         "employee.addEmployee", userId, ex); } 

  在这里,employee.addEmployee上下文将被附加给一个上下文敏感的异常的错误代码,从而产生惟一的错误代码。例如,如果RecordNotFoundException的错误代码是errorcode.recordnotfound,那么这个上下文的最终错误代码将变为errorcode.recordnotfound.employee.addEmployee,它对于这个上下文是惟一的错误代码。

  然而,我们要给出一个警告:如果您准备在同一个客户端方法中使用多个接口,而且这些接口都可以抛出RecordNotFoundException异常,那么想要知道是哪个实体引发了这个异常就变得十分困难。如果业务接口是公共的,而且可以被各种外部客户端使用,那么建议只使用特定的异常,而不使用像RecordNotFoundException这样的一般性异常。特定于上下文的异常对于基于数据库的可恢复异常来说非常有用,因为在这种情况下,异常类始终是相同的,不同的只有它们出现的上下文。

J2EE应用程序的异常层次结构

  正如前面讨论的那样,我们需要定义一个异常基类,叫做BaseAppException,它包含了所有应用程序异常的默认行为。我们将把这个基类放到所有可能抛出checked异常的方法的throws子句中。应用程序的所有checked异常都应该是这个基类的子类。有多种定义错误处理抽象的方式。然而,其中的区别更多地是与业务类而不是与技术有关。对错误处理的抽象可分为以下几类。所有这些异常类都是从BaseAppException派生而来。

checked异常

  • 业务异常:执行业务逻辑时出现的异常。BaseBusinessException是这类异常的基类。
  • 数据库异常:与持久化机制进行交互时抛出的异常。BaseDBException是这类异常的基类。
  • 安全性异常:执行安全性操作时出现的异常。这类异常的基类是BaseSecurityException。
  • 确认异常:在从终端用户处获得确认以执行某个特定任务时使用。这类异常的基类是BaseConfirmationException。

unchecked异常

  • 系统异常:有时候我们希望使用unchecked异常。例如下面的情况:不想亲自处理来自第三方库API的异常,而是希望