7

我们在我们的应用程序中使用 JSF、Spring 和 JPA。我们正在努力简化我们项目的异常处理策略。

我们的应用架构如下:

UI(JSF) --> 托管 Beans --> 服务 --> DAO

我们正在为 DAO 层使用异常翻译 bean 后处理器。这是在 Spring Application Context 文件中配置的。

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> 

Spring将所有数据库异常包装到'org.springframework.dao.DataAccessException'。我们没有在 DAO 层中进行任何其他异常处理。

我们处理异常的策略如下:

表示层:

Class PresentationManangedBean{

 try{
      serviceMethod();
   }catch(BusinessException be){
      // Mapping exception messages to show on UI
   }
   catch(Exception e){
       // Mapping exception messages to show on UI
   }

}

服务层

@Component("service")
Class Service{

 @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = BusinessException.class)
 public serviceMethod(){

  try{

      daoMethod();

   }catch(DataAccessException cdae){
      throws new BusinessException(); // Our Business/Custom exception
   }
   catch(Exception e){
      throws new BusinessException();  //  Our Business/Custom exception
   }
 }

}

DAO 层

@Repository("dao")
Class DAO{

 public daoMethod(){
  // No exception is handled
  // If any DataAccessException or RuntimeException is occurred this 
  // is thrown to ServiceLayer
 }

}

问题: 我们只是想确认上述方法是否符合最佳实践。如果没有,请建议我们处理异常的最佳方法(玩交易管理)?

4

5 回答 5

1

这种方法对我来说看起来不错。我们在我们的项目中使用相同的方法。

维奈

于 2013-02-18T10:46:49.420 回答
1

我使用不同的方法:

-我没有在 DAO 中捕捉到 Spring 的 DAE。我让它们流向控制器(JSF 托管 bean)。

- 在控制器中,我捕获任何异常(只有一个“捕获”)。

-我调用一个自定义的“handleException”方法,该方法接收参数中捕获的异常。

-该异常处理程序检查(例如,使用“if-then-else”语句)参数是哪种异常,并根据该异常向用户显示消息。在我的例子中,我在属性文件中查找要显示的消息,其中消息的键(和参数,如果有的话)是异常的属性(我在抛出异常时将它们放在那里)。特别是,如果你想以一种特殊的方式处理 DAE,你可以在这个异常处理方法中为它放置一个“if”分支,然后用它做任何你想做的事情。

我认为这种方法更好更简洁,因为您只需在一个点进行异常处理,并且您不必在每个级别中都放置这么多的“throw-try-catch”,只需在 Controller (JSF) 中即可。

当然,您可以在服务中针对特定异常使用“try-catch”,如果您想在该特定情况下执行一些业务逻辑,而不是向用户显示消息。

而且,如果您不想在控制器中处理 Spring DAE,您可以将其包装到您自己的业务异常中并重新抛出。但是在服务层而不是在 DAO 中执行此操作。

希望这个答案有帮助。

于 2013-10-02T23:26:27.847 回答
0

也许您可以将 BusinessException 和 BusinessRuntimeException 分开,因为当您捕获 BusinessException 时会抛出 BusinessException,但是当您遇到异常时,您仍然会抛出相同的 BusinessException。尝试将它们分开。顺便说一句,为什么在捕获 BusinessException 时会抛出相同的异常?

于 2014-12-09T14:20:11.820 回答
0

我正在做一些研究,因为我自己对此感到困惑。不过我的看法略有不同。

基本原理是在多层抛出和捕获异常在性能和代码可读性方面的成本很高。关键是服务方法不应该抛出异常。相反,它们应该始终返回一个响应,该响应应该封装状态、​​消息和输出实体。

但是,如果 Controller 调用多个服务方法并尝试根据响应的组合进行绘制,它可以将其放入 try catch 块中并处理异常。

有了这个逻辑,它可以同等地处理 sprint mvc 和 rest mvc。让我知道你的想法。

Class PresentationManangedBean{
      try {
      Response resp1 = serviceMethod();
      if (resp1.getStatus().equals("SUCCESSFUL"))
           // handle UI painting logic.
      else
           // handle error for UI
      Response resp2 = serviceMethod2();
      if (resp.getStatus().equals("SUCCESSFUL"))
           // handle UI painting logic.
      else
           // handle error for UI
      // handle resp1 and resp2 to paint UI.  
     } catch (Exception e) {
           // handle error for UI 
     }
}

1)服务应处理所有异常。控制器不应处理任何异常。2)

于 2015-01-26T16:22:42.310 回答
0

您的方法非常符合 Spring Frameworks 的建议,并且还避免了在应用程序的各个层中渗透大量已检查的异常。

于 2013-06-12T17:12:56.137 回答