我正在开发Spring3.2和Hibernate 3.6,有没有人能解释一下如何在SpringMVC和Hibernate中处理异常......我只是在分享示例代码。
控制器层
public Integer saveEployee(HttpServletRequest req, HttpServletResponse res){
Employee empObj = new Employee();
empObj.setName(req.getParameter("empName"));
......................
......................
Integer empId = materService.saveEmployee(empObj);
return empId;
}
服务层
public Integer saveEmployee(Employee empObj){
return masterDao.saveEmployee(empObj);
}
DAO层
public Integer saveEmployee(Employee empObj){
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Integer empId = session.save(empObj);
tx.commit();
session.close();
return empId;
}
1.现在假设在DAO层保存empObj时发生了任何异常,比如d/b关闭或连接失败,或者发生了任何其他类型的休眠异常,比如ConstraintViolationException
或IntegrityConstraintViolationException
等。
1.是否有可能在控制器层处理NullPointerException
等java异常或任何用户定义的异常等。
那么什么是最佳实践或者如何同时在控制器、服务和DAO层处理异常。
3条答案
按热度按时间ckocjqey1#
根据我在新项目中的经验,
1.不应该在DAO层处理异常。原因:通常我们把@Transactional注解放在服务层。因此我们需要回滚服务层的事务。如果你在DAO处理异常,那么它将不会回滚。跟随下面的链接了解为什么我们应该把@Transaction放在服务层。
Where should "@Transactional" be placed Service Layer or DAO
1.不应在服务层处理异常。原因:由于服务层执行多个DAO进行数据库操作,如果任何DAO失败,我们需要回滚事务。如果我们在服务中处理异常,那么我们可能不会回滚事务。有手动回滚事务的方法,但不建议使用。TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
因此,在控制器层处理异常。
dauxcl2d2#
您不能同时处理应用程序所有级别的异常;你必须考虑它们的上下文含义和你的应用程序的适当策略。2一些错误应该被忽略,一些应该被 Package ,一些应该被允许直接引发。
在
spring-mvc
应用程序中处理异常的一个方法是在适当的地方用你自己的库 Package 来自底层库的致命错误,以抛出它们的级别命名,例如ServiceException
或RepositoryException
。然后,一个@ControllerAdvice
注解的类可以用@ErrorHandler
注解的方法处理这些错误,并返回5XX
http错误。常见的应用程序错误,比如由于
id
不正确而导致实体未被找到,可能会导致自定义异常,例如NotFoundException
被引发并随后在您的@ControllerAdvice
注解类中被捕获。这种技术的优点是在不同的应用程序层中有较少的错误处理代码,并且可以集中异常到响应的转换。
一个示例
@ControllerAdvice
注解类:vu8f3i0k3#
您应该使服务具有事务性,并在控制器层处理异常:您可以选择基于控制器的异常处理(使用
@ExceptionHandler
)或全局异常处理(使用@ControllerAdvice
类)。2在发生异常时,向用户显示一些信息(例如错误页面)可能比较实用。您可以在Spring MVC here中找到异常处理的有用示例。