Spring& S中同时处理Controller,Service和DAO Layer异常的最佳实践是什么?过冬

时间:2015-04-19 14:43:05

标签: java spring hibernate exception

我正在开发Spring 3.2& Hibernate 3.6,任何人都可以解释如何在Sping MVC&中解决异常问题。 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 Layer

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已关闭或连接失败或发生任何其他类型的休眠异常,如ConstraintViolationExceptionIntegrityConstraintViolationException等。< / p>

  2. 如果有可能在控制器层处理NullPointerException或任何用户定义的异常等java异常。

  3. 那么什么是最佳做法或如何同时处理控制器,服务和DAO层的异常。

3 个答案:

答案 0 :(得分:2)

您不能同时处理应用程序各个级别的异常;您必须考虑它们的上下文含义以及适合您的应用程序的策略。一些错误应该被忽略,一些应该被包装,一些应该被允许直接提出。

处理spring-mvc应用程序中的异常的一种方法是使用您自己的适当的方式从底层库中包装致命错误,以它们被抛出的级别命名,例如: ServiceExceptionRepositoryException。然后,@ControllerAdvice - 带注释的类可以使用@ErrorHandler带注释的方法处理这些错误,并返回5XX http错误。

常见的应用程序错误,例如由于错误的id而未找到的实体,可能会导致自定义异常,例如NotFoundException被提出并随后被你的@ControllerAdvice注释课程抓住了。

这种技术的优势在于,您可以在不同的应用程序层中使用较少的错误处理代码,并可以集中将异常转换为响应。

示例@ControllerAdvice - 带注释的类:

@ControllerAdvice
public class ErrorHandler extends ResponseEntityExceptionHandler {
    @ExceptionHandler({NotFoundException.class})
    protected ResponseEntity<Object> handleNotFound(RuntimeException e, WebRequest request) {
        return handleExceptionInternal(e, e.getMessage(),
                null,
                HttpStatus.NOT_FOUND, request);
    }

    @ExceptionHandler({ServiceException.class, RepositoryException.class})
    protected ResponseEntity<Object> handleInternalError(RuntimeException e, WebRequest request) {
        return handleExceptionInternal(e, e.getMessage(),
                null,
                HttpStatus.INTERNAL_SERVER_ERROR, request);
    }
}

答案 1 :(得分:2)

根据我在新项目期间的经验,

  1. 您不应该在DAO层处理异常。 原因:通常我们在服务层放置@Transactional注释。因此我们需要在服务层回滚事务。如果您在DAO处理异常,那么它将不会回滚。 请按照以下链接了解我们为什么要将@Transaction置于服务层 Where should "@Transactional" be place Service Layer or DAO
  2. 您不应在服务层处理异常。 原因:当服务层为数据库操作执行多个DAO时,如果任何DAO失败,我们需要回滚事务。如果我们在服务中处理异常,那么我们可能不会回滚事务。 回滚事务有手动方法,但不建议这样做。 TransactionAspectSupport.currentTransactionStatus()使用setRollbackOnly();
  3. 因此在控制器层处理事务。

答案 2 :(得分:0)

您应该使您的服务具有事务性并在控制器层处理异常:您可以选择基于控制器的异常处理(使用 @ExceptionHandler)或全局异常处理(使用 @ControllerAdvice 类)。 显示一些东西可能是实用的,例如出现异常时向用户显示错误页面。

您可以在 Spring MVC here 中找到有用的异常处理示例。