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

编辑:我已经查看了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的任何逻辑。 所以,我一直在做的是在服务层中放置更复杂的validation和业务逻辑。

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

选项1:例外

我想到的第一种方法是在服务层中引发exception,将其捕获到控制器中并向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传递给Service层

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

服务:

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

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

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

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

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