在springboot项目中,异常处理是一个十分重要却又较为繁琐的一个部分,今天和大家分享一下异常处理的一种实现方式。
步骤如下:
1、 自定义通用异常并继承RuntimeException
public class CustomizeException extends RuntimeException {
private String message;
private int errorCode;
public CustomizeException(ICustomErrorCode error){
message = error.getMessage();`在这里插入代码片`
errorCode = error.getErrorCode();
}
public CustomizeException(int errorCode,String message) {
this.message = message;
this.errorCode = errorCode;
}
}
2、定义枚举接口、实现枚举类
枚举接口
public interface ICustomErrorCode {
public String getMessage();
public int getErrorCode();
}
实现枚举类
public enum CustomizeErrorCode implements ICustomErrorCode {
//枚举类实现异常接口
//定义特定的异常语句为枚举
QUESTION_NOT_FOUND(4001,"尚未登陆,无权访问!(CustomizeExceptionHandler捕获)"),
TARGET_PARAM_NOT_FIND(4002,"内容不能为空!(CustomizeExceptionHandler捕获)"),
SYSTEM_ERROR(500,"出现未知异常,请联系管理员(CustomizeExceptionHandler捕获)");
private String message;
private int errorCode;
@Override
public String getMessage(){
return message;
}
@Override
public int getErrorCode() {
return errorCode;
}
//该构造方法需检查是否赋值this下的变量,否则枚举的message为空
CustomizeErrorCode(int errorCode,String message){
this.errorCode = errorCode;
this.message = message;
}
}
在枚举类中就可以定义在你的项目中所需要抛出的异常
3、最为关键的一步,定义异常handler类,
//用于捕获我们在项目代码中抛出的自定义异常
//捕获后进行相应处理
使用@ControllerAdvice来标识全局异常处理类
@ControllerAdvice
public class CustomizeExceptionHandler {
@ExceptionHandler(Exception.class)
ModelAndView handleControllerException(HttpServletRequest request, HttpServletResponse response, Throwable e, Model model){
//根据contentType判断请求方式,分别处理,对于json请求,避免跳转到错误页面
if(request.getContentType().contains("application/json")){//此处的定义要与前端json定义的contentType一致
ResultDTO resultDTO = null;
if(e instanceof CustomizeException){
resultDTO = ResultDTO.errorOf((CustomizeException) e);
}
else
resultDTO = ResultDTO.errorOf(CustomizeErrorCode.SYSTEM_ERROR);
try {
//构造返回json
response.setCharacterEncoding("utf8");
response.setContentType("application/json");
response.setStatus(200);
PrintWriter writer = response.getWriter();
writer.write(JSON.toJSONString(resultDTO));
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}else {
if(e instanceof CustomizeException){
model.addAttribute("message",e.getMessage());
}
else
//暂时无法处理的,无法处理某些异常
model.addAttribute("message",CustomizeErrorCode.SYSTEM_ERROR.getMessage());
return new ModelAndView("error");
}
}
}
上述异常处理中使用两种方式返回异常信息,一种是json返回,另一种返回model。可以使用request.getContentType().contains(“application/json”)来进行请求方式的甄别,但切记contentType内所判断的字符串要与前端请求的contentType完全相同才能识别出来。
4、处理未控制的异常,即程序发生的未知异常
此处使用@Controller注解,做为一个控制器来处理unhandle异常
@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class ErrorHandleController implements ErrorController {
//处理unhandle的异常,比对BasicErrorController
@Override
public String getErrorPath() {
return "error";
}
@RequestMapping(
produces = {"text/html"}
)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response, Model model) {
HttpStatus status = this.getStatus(request);
//判断status类型
if(status.is4xxClientError()){
model.addAttribute("message","页面请求失败!(ErrorHandleController捕获)");
}
if (status.is5xxServerError()){
model.addAttribute("message","服务器异常!(ErrorHandleController捕获)");
}
return new ModelAndView("error");
}
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 var4) {
return HttpStatus.INTERNAL_SERVER_ERROR;
}
}
}
}
根据status.is4xxClientError()与status.is5xxServerError()来设置不同情况下的错误页显示信息。
springboot的自定义错误页十分简单,在templates目录下加入一个error.html页面,当系统出现错误时,就会返回到你所定义的error.html中。