J2EE分为表示层,业务层,数据访问层. 数据访问层提供基本的数据库增删改查处理,并且是细粒度的,供业务层来调用. 
也就是说业务层所有关于数据库的操作都要直接和数据访问层打交道. 在这里我不想提及关于数据访问层直接抛出check exception,实践已经证明那会让业务层以及整个J2EE层次的异常捕获显得过分臃肿.  
假定数据访问层抛出的是runtime exception. 比如spring的DataAccessException, API规定业务层不需要捕获或抛出这样的异常,但不需要捕获我们真的就可以不捕获吗? 一个被忽略的事实是不管check exception还是runtime exception,只要程序的某个地方出现了异常,程序都会在那个地方停止执行,除非你加了try catch,否则下面的代码就不会执行,程序就死在了那个地方。
假设在表示层有这样的代码:public String saveUser() {userBusiness.saveUser(); return "resultPage"} 假设userBusiness.saveUser();这个业务层调用出现了非检查异常, 如果我们不去捕获,就连下面的return "resultPage"} 都不会执行,用户将会看到一个错误网页,这合适吗?

解决方案 »

  1.   

    心已明镜,数据访问层发生的异常都是跟数据库相关的不可恢复的异常,因此没必要再去区分这些异常的种类,简单的将这些异常
    封装成runtime的自定义异常即可,例如DataAccessException. 而在业务层,我们不能因为数据访问层抛出的是非受控异常就
    不去捕获它,那样将会导致表示层直接处理数据访问层的异常,这是不合理的,表示层只应该关心具有一定业务含义的业务异常。
    因此在业务逻辑层我们需要捕获数据访问异常,并将其封装成为各种具有业务含义的自定义业务异常,例如UserSaveFailedException. 同时在这些业务异常里定义各自的消息字符串,用来做异常输出。 表示层捕获到UserSaveFailedException后进行错误处理和日志的纪录。