1. 自定义异常类
定义接口
public interface Error {
Integer getCode();
String getMessage();
}
先定义一个抽象类为基类,并创建基本的错误信息枚举
public abstract class AbstractBaseError {
public enum BaseErrorEnum implements Error {
ACCOUNT_PASSWORD_FAIL(10001, "账号或密码错误!"),
FORMAT_ERROR(10002, "格式错误【%s】")
;
private int code;
private String message;
BaseErrorEnum(int code, String message) {
this.code = code;
this.message = message;
}
public BaseErrorEnum format(Object... param) {
this.message = String.format(message, param);
return this;
}
@Override
public Integer getCode() {
return this.code;
}
@Override
public String getMessage() {
return this.message;
}
}
}
自定义异常类,继承RuntimeException
public class CustomException extends RuntimeException {
private int code;
public CustomException() {
}
public CustomException(Error error) {
super(error.getMessage());
this.code = error.getCode();
}
public CustomException(int code, String message) {
super(message);
this.code = code;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
@Override
public String getMessage() {
return super.getMessage();
}
}
各个子系统的话可以继承AbstractBaseError,再创建子系统的错误信息枚举
public class Test1Error extends AbstractBaseError {
public enum ErrorEnum implements Error {
TEST1_ERROR_1(11000, "test1 错误1!"),
;
private int code;
private String message;
ErrorEnum(int code, String message) {
this.code = code;
this.message = message;
}
public ErrorEnum format(Object... param) {
this.message = String.format(message, param);
return this;
}
@Override
public Integer getCode() {
return this.code;
}
@Override
public String getMessage() {
return this.message;
}
}
}
2. 统一异常处理
@ControllerAdvice 控制器增强,而@RestControllerAdvice相当于@ResponseBody + @ControllerAdvice。
@ExceptionHandler 拦截异常,统一处理。
可和SpringMVC 统一返回格式中第四点配合使用。
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Map exceptionHandler1(HttpServletRequest request, HttpServletResponse response, Exception e) {
e.printStackTrace();
Map<String, Object> result = new HashMap<>(2);
result.put("code", 500);
String requestUri = request.getRequestURI();
if (requestUri.contains("/api/")) {
result.put("message", "内部异常!");
} else {
if (e.getMessage() == null) {
result.put("message", "内部异常!");
} else {
result.put("message", e.getMessage());
}
}
response.setStatus(500);
return result;
}
}
可和SpringMVC 统一返回格式中第五点配合使用。
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Result<?> exceptionHandler2(HttpServletRequest request, HttpServletResponse response, Exception e) {
e.printStackTrace();
String requestUri = request.getRequestURI();
String message;
if (requestUri.contains("/api/")) {
message = "内部异常!";
} else {
if (e.getMessage() == null) {
message = "内部异常!";
} else {
message = e.getMessage();
}
}
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return Result.failure(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message);
}
}
测试:
@GetMapping("/exception")
public void exception(){
throw new RuntimeException("测试错误错误");
}
@GetMapping("/test1Error")
public void test1Error(){
throw new CustomException(Test1Error.ErrorEnum.TEST1_ERROR_1);
}
@GetMapping("/formatError")
public void formatError(){
throw new CustomException(Test1Error.BaseErrorEnum.FORMAT_ERROR.format("格式化的内容"));
}
参考:
SpringMVC 中 @ControllerAdvice 注解的三种使用场景!
springmvc 通过异常增强返回给客户端统一格式
Spring 异常处理三种方式 @ExceptionHandler
从零搭建Spring Boot脚手架(2):增加通用的功能