Java Spring/JPA/JSF的异常处理策略
我们在应用程序中使用JSF、Spring和JPA。我们正试图简化项目的异常处理策略 我们的应用程序架构如下所示: UI(JSF)-->托管bean-->服务-->DAO 我们正在为DAO层使用异常转换bean后处理器。这是在Spring应用程序上下文文件中配置的Java Spring/JPA/JSF的异常处理策略,java,spring,exception,jpa,exception-handling,Java,Spring,Exception,Jpa,Exception Handling,我们在应用程序中使用JSF、Spring和JPA。我们正试图简化项目的异常处理策略 我们的应用程序架构如下所示: UI(JSF)-->托管bean-->服务-->DAO 我们正在为DAO层使用异常转换bean后处理器。这是在Spring应用程序上下文文件中配置的 <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" /> 服务层 @Componen
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
服务层
@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
}
}
}
@Repository("dao")
Class DAO{
public daoMethod(){
// No exception is handled
// If any DataAccessException or RuntimeException is occurred this
// is thrown to ServiceLayer
}
}
DAO层
@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
}
}
}
@Repository("dao")
Class DAO{
public daoMethod(){
// No exception is handled
// If any DataAccessException or RuntimeException is occurred this
// is thrown to ServiceLayer
}
}
问题:
我们只想确认上述方法是否符合最佳实践。如果没有,请建议我们处理异常的最佳方法(使用事务管理)这种方法对我来说很好。我们在项目中使用相同的方法
Vinay您的方法非常符合Spring框架的建议,并且避免了在应用程序的各个层中渗透大量已检查的异常。我使用了一种不同的方法: -我在刀上抓不到春天的DAE。我让它们流向控制器(JSF托管bean) -在控制器中,我捕获任何异常(只有一个“捕获”) -我调用一个自定义的“handleException”方法,该方法接收在参数中捕获的异常 -该异常处理程序检查(例如,使用“if then else”语句)参数是什么类型的异常,并根据该类型的异常向用户显示消息。在我的例子中,我查找要在属性文件中显示的消息,其中消息的键(以及参数,如果有的话)是异常的属性(我在抛出异常时将它们放在那里)。特别是,如果希望以特殊方式处理DAE,可以在此异常处理程序方法中为其设置一个“if”分支,并对其执行任何操作 我认为这种方法更好、更干净,因为您只在一个点上进行了异常处理,而不必在每个级别上都投入太多的“throws-try-catch”,只需在控制器(JSF)中 当然,如果您想在特定情况下执行某些业务逻辑,而不是向用户显示消息,则可以在服务中针对特定异常使用“try-catch” 而且,如果您不想在控制器中处理SpringDAE,可以将其包装成您自己的业务异常并重新抛出。但这是在服务层中进行的,而不是在DAO中
希望这个答案有帮助。也许您可以将BusinessException和BusinessRuntimeException分开,
因为当你们捕捉到BusinessException抛出BusinessException时,但当你们得到异常时,你们仍然抛出相同的BusinessException。试着把它们分开。顺便问一下,为什么在捕获BusinessException时抛出相同的异常 我正在做一些研究,因为我自己对此感到困惑。然而,我有一个稍微不同的看法 理由是,在多个层上抛出和捕获异常在性能和代码可读性方面代价高昂。关键是服务方法不应该抛出异常。相反,它们应该总是返回一个响应,该响应应该封装状态、消息和输出实体 然而,若控制器调用多个服务方法并尝试基于响应的组合进行绘制,它可以将其放入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) 谢谢您的评论,erhan…我会看一看,然后再联系您。我也想采用这种方法,但当我捕获异常并抛出自定义异常时,我的异常处理程序不会处理该异常。Spring将我的异常包装到
org.springframework.transaction.TransactionSystemException
中。这是我的问题。我如何解决我的问题?