Springboot(10)輕鬆搞定統一異常處理
阿新 • • 發佈:2018-12-26
異常的捕獲方式
方式一 HandlerExceptionResolver介面
實現該介面,註冊到spring容器中,當
controller
中產生異常的時候會呼叫該介面來處理,注意,當返回值指定檢視時會自動跳轉至指定的檢視中去,如果返回null,會繼續呼叫下一個異常處理器去執行
。 springboot中可以通過以下方式去註冊進容器。
@Component
@Slf4j
@Order(Ordered.HIGHEST_PRECEDENCE)
public class MyException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Object o, Exception e) {
log.error("錯誤資訊:",e);
return null;
}
}
這裡可以直接返回ModelAndView物件,跳轉到頁面。如果返回null,則跳轉到/error
方式二 @ControllerAdvice以及@ExceptionHandler
spring 中還可以通過@ControllerAdvice以及@ExceptionHandler(ApplicationException.class)註解對指定的異常做全域性處理
@ControllerAdvice
@Slf4j
public class GlobalExceptionController {
@ExceptionHandler(Exception. class)
public String handlerException(Exception e) {
log.error("控制器增強處理異常");
return "error2";//返回templates/error2.html
}
}
執行完之後會返回一個ModelAndView物件,所以不會再執行我們自己註冊的異常解析器了,要想生效,我們只需在註冊時
調整註冊順序
即可
全域性的異常處理
以上2種方式只能處理Controller層之內的異常,對於渲染層及其他的異常是無能為力的,如果我們要做全域性的異常處理就需要結合容器來做處理了。
例如:404錯誤
以tomcat為例,容器在處理請求時,遇到異常情況,首先會去找錯誤頁面,如果沒有配置錯誤頁面,會HttpStatus預設轉發到/error路徑,所以我們可以寫一個
controller類來處理/error
請求,而springboot中預設有一個處理/error 請求的controller類
@Controller
@RequestMapping("${server.error.path:/error}")
public class GlobalErrorController implements ErrorController {
/**
* 錯誤資訊的構建工具.
*/
@Autowired
private ErrorInfoBuilder errorInfoBuilder;
/**
* 錯誤資訊頁的路徑
*/
private final static String DEFAULT_ERROR_VIEW = "error";
/**
* 獲取錯誤控制器的對映路徑.
*/
@Override
public String getErrorPath() {
return errorInfoBuilder.getErrorProperties().getPath();
}
/**
* 情況1:若預期返回型別為text/html,s則返回錯誤資訊頁(View).
*/
@RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
@ResponseBody
public ModelAndView errorHtml(HttpServletRequest request) {
return new ModelAndView(DEFAULT_ERROR_VIEW,
"errorInfo", errorInfoBuilder.getErrorInfo(request));
}
/**
* 情況2:其它預期型別 則返回詳細的錯誤資訊(JSON).
*/
@RequestMapping
@ResponseBody
public ErrorInfo error(HttpServletRequest request) {
return errorInfoBuilder.getErrorInfo(request);
}
}
樣例測試訪問地址:http://127.0.0.1:8080/exception