编辑:我已经研究了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。
基本上,我不认为验证器中应该包含业务逻辑(超出"此字段为必填项"),尤其是需要访问数据库的任何逻辑。因此,我一直在做的是在服务层中放置更进一步,更复杂的验证和业务逻辑。
例如,假设我有一个页面,允许用户购买一本书。他们单击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与Option 1结合使用,但是我不确定它是否合适(也许我还没有看到合适的示例?)。在上面的示例中,仅出于参数考虑,我希望用户返回到原始表单,但表单上方出现红色错误,而不是重定向到完全不同的页面。当您希望在引发特定异常时将用户重定向到标准错误页面时,SimpleMappingExceptionResolver在我看来很有用(这并不是我想知道的操作)。
我认为选项1将是您最好的选择
Java使用异常自然地处理这种事情。 最后,它通常会通过忘记检查是否存在错误来简化您的逻辑并减少犯错的机会。 您还可以将错误逻辑移出代码的主要流程。
我不明白为什么您提出的情况与我将使用异常处理来处理错误的任何其他情况都不同。
谢谢。 对Spring 3s异常处理程序的进一步研究表明,我可以通过@ExceptionHandler批注在控制器中处理引发的异常,因为我可以像对待请求一样对待它。 在我看来,这似乎比普通rqeuest方法中的try / catching好一些。
@本杰:我不确定@ExceptionHandler方法是否可以访问BindingResult。