System abnormalities often the case in the project, such as NullPointerException and so on. If untreated by default, springboot will respond to a default error message, so the user experience is not a friendly system-level error, the user can not perceive, even if an error 500, may prompt a similar desertion server to the user-friendly tips Wait. This time you can use a global exception handler to deal with global exception elegant
Custom Error Messages class
- The error message will be used to initialize the global exception class
- Note that this message should be rewritten toString method Json format
- Specific initialization error message can also be used when a class% s placeholder, late call the static method, a plurality of parameters to populate
- This uses @Data notes omitted to write your own constructor, the details can find lombook use
@Data
@AllArgsConstructor
@Slf4j
public class CodeMsg implements Serializable {
private int code;
private String msg;
public static CodeMsg SUCCESS = new CodeMsg(200, "success");
public static CodeMsg SERVER_ERROR = new CodeMsg(500100, "服务器错误");
public static CodeMsg INSERT_ERROR = new CodeMsg(500200, "插入错误");
public static CodeMsg UNKNOWN_ERROR = new CodeMsg(-999, "未知错误:%s");
//填充多个错误信息
public static CodeMsg BIND_ERROR = new CodeMsg(500300,"参数校验异常:%s");
public static CodeMsg UNSELECT_FILE_ERROR = new CodeMsg(500400,"未选择文件");
public static CodeMsg FILE_NOT_EXIST_ERROR = new CodeMsg(500500, "文件或文件夹不存在");
public static CodeMsg UPLOADING = new CodeMsg(500600, "正在上传");
//补充未知错误的具体信息
public CodeMsg fillArgs(Object... args){
int code = this.code;
String message = String.format(this.msg,args);
return new CodeMsg(code,message);
}
//处理异常时返回json的toString
@Override
public String toString() {
return "CodeMsg{" +
"code=" + code +
", msg='" + msg + '\'' +
'}';
}
// public static void main(String[] args) {
// log.info(new CodeMsg(0, "hello").toString());
// }
}
Define a global exception classes
- After the encounter any errors, you can use the error message class initialization global exception class, and throw the exception, which will be captured after the global exception handler
//继承RuntimeException,并定义serialVersionUID
public class GlobalException extends RuntimeException {
private static final long serialVersionUID = -3586828184536704147L;
private CodeMsg codeMsg;
public GlobalException(CodeMsg codeMsg) {
super(codeMsg.toString());
this.codeMsg = codeMsg;
}
public CodeMsg getCodeMsg() {
return codeMsg;
}
}
Return result defined class
- Return result there are two, one is to return the corresponding error code, or by returning the correct code + data, so we write class return results
@Data
@ApiModel(description = "返回结果")
public class Result<T> implements Serializable {
private int code;
private T data;
private String msg;
private Result(T data) {
this.code = 0;
this.msg = "success";
this.data = data;
}
private Result() {
this.code = 0;
this.msg = "success";
this.data = null;
}
private Result(CodeMsg codeMsg) {
if (codeMsg == null) {
return;
}
this.code = codeMsg.getCode();
this.msg = codeMsg.getMsg();
}
public static <T> Result<T> success(T data) {
return new Result<T>(data);
}
public static <T> Result<T> success() {
return new Result<T>();
}
public static <T> Result<T> error(CodeMsg codeMsg) {
return new Result<T>(codeMsg);
}
}
Define a global exception handler
- Use @ControllerAdvice to specify global exception handler
- Use @RestController return json data
- Use @ExceptionHandler to capture a particular type of abnormality
@ControllerAdvice
@RestController
@Slf4j
public class GlobalExceptionHandler {
//自定义异常类
@ExceptionHandler(value = GlobalException.class)
public Result<String> globalExceptionHandler(HttpServletRequest request, GlobalException e) {
log.error(e.getCodeMsg().getMsg());
return Result.error(e.getCodeMsg());
}
//参数检测不合格
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public Result<String> bindExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException e) {
log.error(e.getClass().toString());
// log.error(e.toString());
List<ObjectError> errors = e.getBindingResult().getAllErrors();
StringBuilder errorMsg = new StringBuilder();
//此处仅取第一个
// ObjectError objectError = errors.get(0);
for (ObjectError error : errors) {
errorMsg.append(error.getDefaultMessage()).append(" ");
}
// String errorMsg = objectError.getDefaultMessage();
//填充具体异常
return Result.error(CodeMsg.BIND_ERROR.fillArgs(errorMsg.toString()));
}
//其他异常类
@ExceptionHandler(value = Exception.class)
public Result<String> defaultExceptionHandler(HttpServletRequest request, Exception e) {
log.error(e.getClass().toString());
log.error(e.toString());
e.printStackTrace();
return Result.error(CodeMsg.UNKNOWN_ERROR.fillArgs(e.getClass().toString()));
}
//可定义详细的其他异常类
// @ExceptionHandler(AuthenticationException.class) //此处为shiro未登录异常类
// @ResponseStatus(HttpStatus.UNAUTHORIZED)
// public String unAuth(AuthenticationException e) {
// log.error("用户未登陆:", e);
// return "/login.html";
// }
}
Effect
so far, we will complete the global self-defined exception handling, visit the following effect
//成功
{
code = 0;
msg = "success";
data = 456;
}
//失败
{
code = 500100;
msg = "服务器错误";
data = null;
}
Above are some of my own thoughts, to share out the welcome to correct me, the way to find a wave of attention
of: LeoMalik
link: https: //juejin.im/post/5e54796af265da575d20dd5d
Source: Nuggets