今天的博客探討了使用@ 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