SpringBoot全局异常处理

在SpringMVC中可以使用ControllerAdvice来做controller内部的全局异常处理,但对于未进入controller前的异常,该处理方法是无法进行捕获处理的,SpringBoot提供了ErrorController的处理类来处理所有的异常。

 

20190530补充:

springboot提供了/error的错误管理端点和默认的BasicErrorController实现类,但这个Controller实现类其实不一定符合我们的需求,所以我们才需要来覆盖这个默认实现。

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

下面的类是直接实现了ErrorController,其实我们也可以仿照BasicErrorController来继承AbstractErrorController减少一些代码的编写。

  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 }
原文地址:https://www.cnblogs.com/yangzhilong/p/7904665.html