【问题标题】:Exception handling in spring春季异常处理
【发布时间】:2014-12-13 16:25:16
【问题描述】:

我正在使用 spring + hibernate 开发 Web 应用程序。据我所知,将@transactional 放在服务层是最佳实践。 Spring在将数据更新到数据库时抛出DataAccessException异常。

下面是我的高级类结构。

@Transactional
class OrderService {
    public void createOrder() {
        try {
           orderDAO.createOrder();
        } catch (DataAccessException e) {
            // convert into business exception and sends back to presentation logic.
        }
    }

}

这里发生的是只有在方法完成后才抛出数据访问异常。因此,如果发生任何异常,我无法将其转换为 catch 块中的业务异常。

解决方法是在 dao 方法中刷新休眠会话,但我不喜欢这种方法。有没有更好的方法来解决这个问题?

【问题讨论】:

  • 你可以使用 AOP 拦截器,但是为什么呢? DataAccessException 有什么问题? Spring 已经提供了一个异常层次结构,可以将您与持久性框架特定的异常类型隔离开来。为什么还要在此之上再添加一个异常层次结构?
  • 我想向用户提供自定义消息。不是春天给的。除了 AOP 抛出建议之外,您还有其他选择吗?
  • 那你为什么不在 UI 层捕获 DataException 呢?显示错误消息不是服务层的工作。
  • 我的表示层不应该知道数据库和其他东西。因此我的设计在表示层中没有这样的逻辑。我的观点是服务层应该完成所有工作。

标签: spring hibernate exception-handling transactional


【解决方案1】:

我假设您使用的是 Spring MVC,尽管您没有指定。如果您使用的是 Spring MVC,那么有几个不同的选项。

  1. 您可以创建一个过滤器来查找 DAE 异常并将其重新编码为您的前端可以更好地理解的不同状态或异常。您可以查看 Spring Security 的 ExceptionTranslationFilter 作为示例,了解如何针对不同的异常完成此操作
  2. 您可以使用SimpleMappingExceptionResolver 将特定异常映射到特定视图。这将允许您的表示层是不可知的,并且不需要知道关于抛出的异常的任何信息。
  3. 您可以在特定控制器中使用@ExceptionHandler 以一般方式处理 DAE 异常,并为表示层适当地准备一些东西。
  4. 作为 #3 的扩展,您可以使用 @ControllerAdvice 来管理 web 应用中任何控制器的所有 DAE 异常。

您也可以阅读Exception Handling in Spring MVC 了解更多详情。

一般来说,我发现最好的解决方案是在更高级别捕获事务异常,并操纵信息以与后端无关的方式将其呈现给前端。这允许您设置自己的错误代码/等。我在服务本身中尝试/捕获异常的唯一时间是,如果我真的想尝试重试或根据某些特定异常修改逻辑流并且不希望前端知道它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多