Spring MVC之異常處理
阿新 • • 發佈:2019-02-03
一、概況
正常情況下,請求到達服務端,服務端處理完成後返回資料結果(RESTful前後端分離)或返回頁面(傳統jsp web工程),這樣一次完整的流程就走完了。
異常情況下,如404/405/400/500/302/都是由容器或自定義頁面返回給使用者。在現在開發中(RESTful 介面),我們需要一個穩定的報文格式返回,包括異常請求情況,這就需要程式感知並處理所有的異常情況。SpringMVC就提供這個機制,統一處理Controller異常;這樣對介面的使用者就非常友好,且提示資訊明確,減少溝通成本(HEATOS)
異常處理之前返回的結果:
異常處理之後:
二、實現方式
註解@ExceptionHandler,用於異常處理,因所有的請求都需要進行異常處理,所以我們寫一個抽象類讓所有Controller繼承;
在ExceptionHandler上加上 @ResponseBody 註解,這樣異常程式碼提示就可以直接返回到使用者端了public abstract class BaseController { protected final Logger logger = LoggerFactory.getLogger(BaseController.class); /** 異常處理 */ @ResponseBody @ExceptionHandler(Exception.class) public ResponseEntity<ModelMap> exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) throws Exception { ModelMap modelMap = new ModelMap(); ResponseEntity<ModelMap> result = null; if (ex instanceof HttpRequestMethodNotSupportedException) { result = setModelMap(modelMap, HttpStatus.METHOD_NOT_ALLOWED); } else if (ex instanceof MissingServletRequestParameterException) { result = setModelMap(modelMap, HttpStatus.BAD_REQUEST); } else if (ex instanceof IllegalArgumentException) { result = setModelMap(modelMap, HttpStatus.BAD_REQUEST); } else { result = setModelMap(modelMap, HttpStatus.INTERNAL_SERVER_ERROR); logger.error("INTERNAL_SERVER_ERROR ", ex); } String message = ex.getMessage(); if (!StringUtils.isBlank(message)) { modelMap.put("msg", message); } if (logger.isDebugEnabled()) { logger.debug(ex.getMessage(), ex); } return result; } }
上面的程式碼有一個問題:就是405的異常(HtttpRequestMethodNotSupportException)攔截不到,沒有進入ExeptionHandler的處理邏輯中;原因:因為GET 沒有相應的RequestMapping請求對映找不到相應的controller,就無法觸發異常攔截;
解決:@ControllerAdvice註解,把使用@ExceptionHandler、@InitBinder、@ModelAttribute註解的方法應用到所有的 @RequestMapping註解的方法;