今天的博客探讨了使用@ ExceptionHandler批注创建简单的Spring 3 servlet异常处理程序的场景。 尽管您可能在此之前就已经看到了它,但它为我提供了一个很好的起点。在本演示中,我创建了一个简单的Spring 3 MVC webapp( 1),其中主页( home.jsp )向不稳定的控制器类发出请求引发异常( ExceptionDemoController )
/*** Whoops, throw an IOException*/@RequestMapping(value = "/ioexception", method = RequestMethod.GET)public String throwIoException(Locale locale, Model model) throws IOException {logger.info("This will throw an IOExceptiom");boolean throwException = true;if (throwException) {throw new IOException("This is my IOException");}return "home";}
上面的不稳定控制器代码是生成错误的第一步。 这个想法是应该让用户返回我们的主页,但是在处理用户请求的过程中,它抛出了一个简单的IOException 。 一旦引发,此方法将捕获异常:
/*** Catch IOException and redirect to a 'personal' page*/@ExceptionHandler(IOException.class)public ModelAndView handleIOException(IOException ex) {logger.info("handleIOException - Catching: " + ex.getClass().getSimpleName());return errorModelAndView(ex);}/*** Get the users details for the 'personal' page*/private ModelAndView errorModelAndView(Exception ex) {ModelAndView modelAndView = new ModelAndView();modelAndView.setViewName("error");modelAndView.addObject("name", ex.getClass().getSimpleName());modelAndView.addObject("user", userDao.readUserName());return modelAndView;}
设置起来非常简单,您需要做的就是添加:
@ExceptionHandler(IOException.class)
…对于方法签名,等等,您已经完成了…这就是简单的工作。
这里有一些值得注意的地方:首先,使用
@ExceptionHandler(IOException.class)
…将遵守通常的例外处理合同。 这意味着上述方法不仅将捕获所有IOExceptions ,还将捕获作为IOException子类的所有异常; 因此,如果我的throwAnException (..)方法抛出FileNotFoundException,它仍然会被我的handleIOException (...)方法捕获。
其次,有一组非常灵活但最终有限的方法签名,可用于异常处理程序方法。 完整的文档由Spring的JavaDoc提供 ,但总而言之,您可以设计一个签名,该签名包含任意顺序的以下任何输入参数:
- 异常或其子类之一
- ServletRequest或HttpServletRequest
- ServletResponse或HttpServletResponse
- HttpSession
- WebRequest或NativeWebRequest
- 语言环境
- InputStream或其子类之一来访问请求的内容
- OutputStream或其子类之一来访问响应的内容
- 读者或其子类别之一
- 作家或其子类别之一
方法签名还必须具有以下返回类型之一:
- 模型和视图
- 模型
- 地图
- 视图
- 字符串–解释为视图名称
- 无效,但前提是该方法直接写入响应对象
所有这些在任何情况下都足以满足任何情况。
使用@ ExceptionHandler使您能够执行针对不同错误情况的细粒度异常处理。 在示例代码的情况下,我创建了一个新的ModelAndView对象,并用用户名填充该对象,以便亲自告诉他(她)系统丢失了他们的文档。 有人可能会说这是一个限制,因为@ExceptionHandler的粒度是如此之细,以致您只能捕获包含@ExceptionHandler注释方法的控制器抛出的异常 。 我不同意,如果您想在一个地方捕获多个控制器抛出的异常,那么该技术不适合您,您应该考虑使用SimpleMappingExceptionResolver 。
实施错误处理时要考虑很多因素,例如:如果错误处理程序中存在错误,会发生什么? 您应该使用粗粒度还是细粒度异常处理程序? 如何设置HTTP状态代码? 因此,接下来的几篇博客将进一步研究错误处理,演示如何将多个异常类分配给单个@ExceptionHandler以及如何将异常处理程序符号与@ResponseStatus结合起来以微调服务器的HTTP状态代码,并且可能还会更多……
参考:来自JCG合作伙伴的 Spring 3 MVC异常处理程序 调试队长博客的 Roger Hughes。
- 完整的Webapp示例可在以下位置获得:
git://github.com/roghughe/captaindebug.git - 请参阅Spring文档以获取参考资料。
翻译自: https://www.javacodegeeks.com/2012/02/spring-3-mvc-exception-handlers.html