将错误从服务层传递回视图

时间:2010-07-11 21:49:23

标签: java spring spring-mvc

编辑:我查看了Spring 3的@ExceptionHandler注释,并将其与下面的选项1 相结合,看起来是一个非常干净的解决方案。

请参阅http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-exceptionhandlers

我还发现这是一本很好的读物:http://blog.decaresystems.ie/index.php/2006/04/07/difficult-choices-in-handling-exceptions-in-enterprise-java-applications/


我一直在使用Spring MVC框架进行开发一段时间,但是我正在努力想出一种“好的”方法来将服务层中引发的错误传递回JSP。

基本上,我不认为业务逻辑(超出“此字段是必需的”)应该在Validators中,尤其是需要访问DB的任何逻辑。所以,我一直在做的是在服务层中放置更复杂的验证和业务逻辑。

例如,假设我有一个允许用户购买图书的页面。他们在JSP上单击“购买”,控制器调用服务使其全部发生......现在,如果服务看到他们没有足够的资金会发生什么 - 我如何将这个消息发送回JSP这么好的一点点可以向用户显示“资金不足”消息?我考虑了两种方法,我不确定哪种方法是正确的......

选项1:例外

我认为第一种方法是在服务层中引发异常,将其捕获到控制器中并向BindingResult添加消息。

服务:

public void pay(Book book) throws InsufficientFundsException {
    // Some logic goes here, which ends up throwing the above exception
}

控制器:

public ModelAndView(@ModelAttribute("book") Book book, BindingResult errors) {
    try {
        pay(book);
    } catch (InsufficientFundsException ex) {
        errors.reject("insufficient.funds");
    }
    return new ModelAndView(blahblahblah);
}

选项2:将BindingResult传递给服务层

第二种方法是将BindingResult对象传递给服务层并针对它引发更多错误。

服务:

public void pay(Book book, BindingResult errors) {
    // User has insufficient funds, so...
    errors.reject("insufficient.funds);
}

我可以看到这两种方式的问题。选项1感觉很尴尬,因为我不仅要捕获异常,然后我必须将错误添加到绑定结果中,这样我觉得我做了两次同样的事情。选项2似乎将服务层与控制器绑定得太紧。

最后,我意识到SimpleMappingExceptionResolver可以与选项1一起使用,但我不确定它是否合适(也许我没有看到一个合适的例?)。在上面的例子中,我们只是为了论证而说,我希望用户返回到原始表单,表单上方有一个红色错误,而不是重定向到一个完全不同的页面。当你想要在引发某个异常时将用户重定向到标准错误页面时,我认为SimpleMappingExceptionResolver非常有用(这不是我想知道的怎么做)。

1 个答案:

答案 0 :(得分:4)

Java使用异常来自然地处理这种事情。最后,它通常会简化您的逻辑,并通过忘记检查出现错误来减少犯错误的可能性。您还可以将错误逻辑移出代码的主流。

我不明白为什么你提出的案例与我将使用异常处理来处理错误的任何其他案例不同。