【问题标题】:Handling expected exceptions from dao处理来自 dao 的预期异常
【发布时间】:2021-11-20 23:37:13
【问题描述】:

我目前正在编写一个包含三层(控制器 -> 服务 -> dao)的 spring-mvc (jsp) 项目,我想知道处理来自 dao 调用的预期异常的正确方法是什么(例如,尝试持久化用户已经存在,如果存在,则再次调用注册视图并显示用户已存在的消息),起初我认为在 dao 中捕获异常(例如 DataIntegrityViolationException)并抛出我的任意检查是个好主意异常,所以我可以在控制器中为它做一个异常处理程序,但我担心如果我这样做,那么如果我想稍后创建我的服务方法@Transactional,我可能会发生冲突,因为 spring 不知道如何回滚事务。

如果这是正确的,那么我有两个想法:

  1. 当我调用服务调用 userService.register(..) 时,在控制器中尝试/捕获 DataAccessException

  2. 在控制器中使用诸如 userService.findByUsername(username) 之类的东西(它返回一个 Optional),如果它存在,我什至在调用 userService.register(..) 之前通知用户

另外,我们的老师强调遵循 DDD 行为并试图避免在我们的控制器中泄漏业务逻辑,我担心这两种解决方案都会这样做,但我真的不知道如何处理它。

【问题讨论】:

    标签: spring spring-mvc exception dao


    【解决方案1】:

    Spring 已经将已检查的 JDBC 异常转换为信息量更大的未检查异常,这些异常与服务层事务配合得很好。您所有的自定义检查异常都会强制您输入更多内容。 Spring 为您提供了合理的默认值,请充分利用它们。

    创建一个异常处理程序。 Spring 有多种方法来实现这一点,它们都不涉及在控制器中为异常编写 catch 块。

    将业务逻辑放在服务中,而不是控制器中。看起来您的 findByUsername 和 register 可以组合在一个事务服务方法中。

    【讨论】:

    • 我看到的问题是,如果我确实为 DataAccessException 创建了一个异常处理程序,我如何确定处理异常后返回的位置? (例如,当主键重复时,每个将条目持久化到数据库的服务都会抛出相同的异常,如果我想显示一条消息说“这个'x'字段已经在使用中”,我不会知道要返回哪个视图)。
    • 对不起,如果我没有正确理解这一点,但如果您正在注册用户并且用户名已经在使用中,您不想返回注册视图/显示一条消息说用户名正在使用的表单?
    • @Delsh:您描述的示例更多的是验证消息。真的不需要抛出异常,你可以返回一些东西来表明注册是否有效。
    • @Delsh:在某些情况下,捕获异常可能会起作用。但是在某些情况下您将需要一个异常处理程序,并且转到一个专用的错误页面就可以了,因为对于诸如数据库关闭之类的错误,您无论如何都无法填充视图的其余部分。 (假设这不是 SPA。)
    猜你喜欢
    • 2020-12-16
    • 1970-01-01
    • 2010-12-09
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多