public abstract class BaseException extends RuntimeException {
private static final long serialVersionUID = 310158626341330120L;
private int errorCode;
BaseException() {
this((ResultCode)ResultCodeEnum.SYSTEM_ERROR);
}
BaseException(ResultCode errorCode) {
super(errorCode.getMsg());
this.errorCode = errorCode.getCode();
}
BaseException(Throwable cause) {
this(ResultCodeEnum.SYSTEM_ERROR, cause);
}
BaseException(ResultCode errorCode, Throwable cause) {
super(errorCode.getMsg(), cause);
this.errorCode = errorCode.getCode();
}
BaseException(ResultCode errorCode, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(errorCode.getMsg(), cause, enableSuppression, writableStackTrace);
this.errorCode = errorCode.getCode();
}
public int getErrorCode() {
return this.errorCode;
}
}
public class BusinessException extends BaseException {
private static final long serialVersionUID = -5829201794325483291L;
public BusinessException() {
}
public BusinessException(ResultCode errorCode) {
super(errorCode);
}
public BusinessException(Throwable cause) {
super(cause);
}
public BusinessException(ResultCode errorCode, Throwable cause) {
super(errorCode, cause);
}
}
@ControllerAdvice({"com.xx", "cn.xx"})
@Configuration
// 可以直接使用@RestControllerAdvice,等于@ControllerAdvice加上 @ResponseBody
public class GlobalExceptionHandler {
private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);
public GlobalExceptionHandler() {
}
@ResponseBody
@ExceptionHandler({BaseException.class})
public Result baseExceptionHandler(HttpServletRequest req, BaseException ex) {
LOG.error("ERROR!GET REQUEST URL :", req.getRequestURI());
LOG.error("errorCode=" + ex.getErrorCode(), ex);
return new Result(ex.getErrorCode(), ex.getMessage(), ex.getMessage());
}
@ResponseBody
@ExceptionHandler({Exception.class})
public Result otherExceptionHandler(HttpServletRequest req, Exception ex) {
LOG.error("ERROR!GET REQUEST URL :", req.getRequestURI());
LOG.error(ex.getMessage(), ex);
return new Result(ResultCodeEnum.SYSTEM_ERROR);
}
@ResponseBody
@ExceptionHandler({ParamValidException.class})
public Result methodArgumentNotValidHandler(HttpServletRequest req, ParamValidException ex) {
LOG.error("ERROR!GET REQUEST URL :", req.getRequestURL());
LOG.error(ex.getMessage(), ex);
FieldValidError fieldValidError = ex.getFieldValidError();
return new Result(Integer.parseInt(fieldValidError.getCode()), fieldValidError.getMessage(), fieldValidError.getMessage());
}
@ResponseBody
@ExceptionHandler({MethodArgumentNotValidException.class})
public Result methodArgumentNotValidHandler1(HttpServletRequest req, MethodArgumentNotValidException ex) {
LOG.error("ERROR!GET REQUEST URL :", req.getRequestURL());
LOG.error(ex.getMessage(), ex);
BeanPropertyBindingResult bindingResult = (BeanPropertyBindingResult)ex.getBindingResult();
FieldValidError fieldValidError;
if (bindingResult.hasErrors()) {
FieldError fieldError = bindingResult.getFieldError();
fieldValidError = ValidMessageUtils.returnFieldValidError(fieldError.getField(), fieldError.getDefaultMessage());
} else {
fieldValidError = new FieldValidError((String)null, String.valueOf(ResultCodeEnum.INVALID_REQUEST.getCode()), ResultCodeEnum.INVALID_REQUEST.getMsg());
}
return new Result(Integer.parseInt(fieldValidError.getCode()), fieldValidError.getMessage(), fieldValidError.getMessage());
}
}
Filter中抛出异常@RestControllerAdvice注解无法捕获的问题
原因:
请求进来 会按照 filter -> interceptor -> controllerAdvice -> aspect -> controller的顺序调用
当controller返回异常 也会按照controller -> aspect -> controllerAdvice -> interceptor -> filter来依次抛出
这种Filter发生的404、405、500错误都会到Spring默认的异常处理。如果你在配置文件配置了server.error.path的话,就会使用你配置的异常处理地址,如果没有就会使用你配置的error.path路径地址,如果还是没有,默认使用/error来作为发生异常的处理地址。如果想要替换默认的非Controller异常处理直接实现Spring提供的ErrorController接口就行了
方法一
新建MyErrorController并继承BasicErrorController
import cn.hutool.core.util.ObjectUtil;
import com.iof.upms.common.result.Result;
import io.swagger.annotations.Api;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@RestController
@Api(value = "filter错误处理", description = "filter错误处理")
public class MyErrorController extends BasicErrorController {
public MyErrorController() {
super(new DefaultErrorAttributes(), new ErrorProperties());
}
@Override
@RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
getErrorProperties().setIncludeException(true);
getErrorProperties().setIncludeMessage(ErrorProperties.IncludeAttribute.ALWAYS);
getErrorProperties().setIncludeStacktrace(ErrorProperties.IncludeAttribute.ALWAYS);
Map<String, Object> body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL));
HttpStatus status = getStatus(request);
//错误信息
Object obj = body.get("message");
//获取异常信息
String exception = String.valueOf(body.get("exception"));
//如果是shiro异常则返回666,否则返回500
int code = "org.apache.shiro.authc.AuthenticationException".equals(exception) ? 666 : 500;
return new ResponseEntity(Result.error(code, ObjectUtil.isNull(obj) ? "系统异常,请重新登录!" : String.valueOf(obj)), HttpStatus.OK);
}
}
方法二
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
@RestController
public class ErrorControllerImpl implements ErrorController {
@Override
public String getErrorPath() {
return "/error";
}
@RequestMapping("/error")
public void handleError(HttpServletRequest request) throws Throwable {
if (request.getAttribute("javax.servlet.error.exception") != null) {
throw (Throwable) request.getAttribute("javax.servlet.error.exception");
}
}
}
本文介绍如何在SpringBoot项目中进行全局异常处理,包括自定义异常类、使用@RestControllerAdvice进行异常捕获及处理,同时还提供了两种实现非Controller异常处理的方法。
1459






