Springboot项目全局异常统一处理
package com.youzan.cloud.ddyl.web;
import com.youzan.cloud.ddyl.api.BizCodeConst;
import com.youzan.cloud.ddyl.api.BizServiceException;
import com.youzan.cloud.ddyl.web.support.UnauthorizedException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.util.NestedServletException;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
/**
* @author bomee shiaupo@qq.com
* @since 2020/9/5
*/
@Controller
@ControllerAdvice
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class JsonResultErrorController implements ErrorController {
@Value("${server.error.path:${error.path:/error}}")
private String errorPath;
@RequestMapping
public ResponseEntity<JsonResult<?>> error(HttpServletRequest request) {
Throwable error = getError(request);
HttpStatus status = getStatus(request);
return new ResponseEntity<>(
new JsonResult<>(status.value(), "服务器当前不能处理该请求", ((Supplier<String>) () -> {
Throwable ex = error;
while (ex != null) {
if (!Objects.isNull(ex.getMessage())) {
return ex.getMessage();
}
ex = ex.getCause();
}
return null;
}).get()), status);
}
@ExceptionHandler(UnauthorizedException.class)
@ResponseBody
public ResponseEntity<JsonResult<?>> handleException(UnauthorizedException exception) {
return new ResponseEntity<>(
new JsonResult<>(HttpStatus.UNAUTHORIZED.value(), exception.getMessage(), null),
HttpStatus.UNAUTHORIZED);
}
@ExceptionHandler(BizServiceException.class)
@ResponseBody
public ResponseEntity<JsonResult<?>> handleException(BizServiceException exception) {
return new ResponseEntity<>(
new JsonResult<>(exception.getCode() == null ? BizCodeConst.BIZ_UNDEFINED_EX : exception.getCode(), exception.getMessage(), null),
HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseEntity<JsonResult<?>> handleException(MethodArgumentNotValidException exception) {
return new ResponseEntity<>(
new JsonResult<>(HttpStatus.BAD_REQUEST.value(), exception.getBindingResult().getAllErrors().get(0).getDefaultMessage(), null),
HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseBody
public ResponseEntity<JsonResult<?>> handleException(MissingServletRequestParameterException exception) {
return new ResponseEntity<>(
new JsonResult<>(HttpStatus.BAD_REQUEST.value(), "缺失请求参数" + exception.getParameterName(), null),
HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseBody
public ResponseEntity<JsonResult<?>> handleException(HttpRequestMethodNotSupportedException exception) {
return new ResponseEntity<>(
new JsonResult<>(HttpStatus.METHOD_NOT_ALLOWED.value(), exception.getMethod() + "不被支持", null),
HttpStatus.METHOD_NOT_ALLOWED);
}
protected HttpStatus getStatus(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
if (statusCode == null) {
return HttpStatus.INTERNAL_SERVER_ERROR;
} else {
try {
return HttpStatus.valueOf(statusCode);
} catch (Exception e) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
}
}
protected Throwable getError(HttpServletRequest request) {
Throwable throwable =
(Throwable) Optional.ofNullable(request.getAttribute("javax.servlet.error.exception"))
.orElseGet(() -> request.getAttribute(DispatcherServlet.EXCEPTION_ATTRIBUTE));
if (throwable instanceof NestedServletException) {
return throwable.getCause();
}
return throwable;
}
@Override
public String getErrorPath() {
return errorPath;
}
}
package com.youzan.cloud.ddyl.api;
/**
* 业务异常基类
*
* @author bomee shiaupo@qq.com
* @since 2020/9/13
*/
public class BizServiceException extends RuntimeException {
private final Integer code;
public BizServiceException(String message, Throwable e) {
this(null, message, e);
}
public BizServiceException(Integer code, String message) {
this(code, message, null);
}
public BizServiceException(Integer code, String message, Throwable e) {
super(message, e);
this.code = code;
}
/**
* 尽可能为每个业务异常划分一个Code
*
* @return Code
*/
public Integer getCode() {
return code;
}
}
package com.youzan.cloud.ddyl.api.exception;
import com.youzan.cloud.ddyl.api.BizCodeConst;
import com.youzan.cloud.ddyl.api.BizServiceException;
/**
* @author bomee shiaupo@qq.com
* @since 2020/9/19
*/
public class ActivityTimeConflictException extends BizServiceException {
public ActivityTimeConflictException(String message) {
super(BizCodeConst.ACT_TIME_CONFLICT, message, null);
}
}
重试
https://toutiao.io/posts/rhskkte/preview
https://yq.aliyun.com/articles/609440
https://juejin.im/post/6844904102468517895
https://blog.csdn.net/u011116672/article/details/77823867