SpringBoot全局異常處理

在SpringMVC中能夠使用ControllerAdvice來作controller內部的全局異常處理,但對於未進入controller前的異常,該處理方法是沒法進行捕獲處理的,SpringBoot提供了ErrorController的處理類來處理全部的異常。java

 

20190530補充:web

springboot提供了/error的錯誤管理端點和默認的BasicErrorController實現類,但這個Controller實現類其實不必定符合咱們的需求,因此咱們才須要來覆蓋這個默認實現。spring

其中:BasicErrorController extend AbstractErrorController ,AbstractErrorController  又 implements ErrorController。springboot

下面的類是直接實現了ErrorController,其實咱們也能夠仿照BasicErrorController來繼承AbstractErrorController減小一些代碼的編寫。app

 

  1 import java.util.Map;
  2 
  3 import javax.servlet.http.HttpServletRequest;
  4 
  5 import org.springframework.beans.factory.annotation.Autowired;
  6 import org.springframework.boot.autoconfigure.web.ErrorAttributes;
  7 import org.springframework.boot.autoconfigure.web.ErrorController;
  8 import org.springframework.http.HttpStatus;
  9 import org.springframework.web.bind.annotation.RequestMapping;
 10 import org.springframework.web.bind.annotation.ResponseStatus;
 11 import org.springframework.web.bind.annotation.RestController;
 12 import org.springframework.web.context.request.RequestAttributes;
 13 import org.springframework.web.context.request.ServletRequestAttributes;
 14 
 15 import com.tomato.boss.common.base.ResponseResult;
 16 
 17 import lombok.extern.slf4j.Slf4j;
 18 import springfox.documentation.annotations.ApiIgnore;
 19 
 20 /**
 21  * 全局異常處理,當異常被@ControllerAdvice時不會走到這個處理類,沒被處理時會走到這裏
 22  * 例如 @valid入參校驗失敗的是不會走ControllerAdvice的,但會走這個處理器
 23  * @author yangzhilong
 24  *
 25  */
 26 @RestController
 27 @ApiIgnore
 28 @Slf4j
 29 public class GolablExceptionEndpoint implements ErrorController{
 30     
 31     private static final String PATH = "/error";
 32     
 33     @Autowired
 34     private ErrorAttributes errorAttributes;
 35 
 36     @Override
 37     public String getErrorPath() {
 38         return PATH;
 39     }
 40     
 41     /**
 42      * 全局異常處理
 43      * 增長@ResponseStatus註解將非200的http狀態碼轉成200
 44      * @return
 45      */
 46     @RequestMapping(value = PATH)
 47     @ResponseStatus(code=HttpStatus.OK)
 48     public ResponseResult<Object> error(HttpServletRequest request) {
 49         return handlerError(request, false);
 50     }
 51     
 52     /**
 53      * 具體的處理
 54      * @param request
 55      * @param includeStackTrace
 56      * @return
 57      */
 58     private ResponseResult<Object> handlerError(HttpServletRequest request, boolean includeStackTrace) {
 59         RequestAttributes requestAttributes = new ServletRequestAttributes(request);
 60         Throwable e = errorAttributes.getError(requestAttributes);
 61         
 62         Map<String, Object> data = errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace);
 63         
 64         String message = null;
 65         StringBuilder detailMessage = new StringBuilder("");
 66         
 67         HttpStatus status = getStatus(request);
 68         if(status == HttpStatus.BAD_REQUEST) {
 69             log.error("參數校驗失敗", e);
 70             message = "請檢查數據填寫是否合法";
 71         } else if(status == HttpStatus.INTERNAL_SERVER_ERROR) {
 72             log.error("系統錯誤", e);
 73             message = "系統繁忙";
 74         } else if(status == HttpStatus.NOT_FOUND) {
 75             log.error("404錯誤");
 76             message = "服務或者頁面不存在";
 77         } else {
 78             log.error("系統錯誤", e);
 79             message = "系統出錯,未知錯誤";
 80         }
 81         if(null != data.get("error")) {
 82             detailMessage.append(String.valueOf(data.get("error"))).append(":");
 83         }
 84         if(null == e || null == e.getMessage()) {
 85             if(null != data.get("message")) {
 86                 detailMessage.append(String.valueOf(data.get("message")));
 87             }
 88         } else {
 89             detailMessage.append(e.getMessage());
 90         }
 91         
 92         return ResponseResult.buildFailResponse(String.valueOf(data.get("status")), message, detailMessage.toString());
 93     }
 94     
 95     /**
 96      * 獲取錯誤編碼
 97      * @param request
 98      * @return
 99      */
100     private HttpStatus getStatus(HttpServletRequest request) {
101         Integer statusCode = (Integer) request
102                 .getAttribute("javax.servlet.error.status_code");
103         if (statusCode == null) {
104             return HttpStatus.INTERNAL_SERVER_ERROR;
105         }
106         try {
107             return HttpStatus.valueOf(statusCode);
108         }
109         catch (Exception ex) {
110             return HttpStatus.INTERNAL_SERVER_ERROR;
111         }
112     }
113 }
相關文章
相關標籤/搜索