SpringBoot 全局异常处理
- Java异常处理,见菜鸟教程说明如下
Java异常
分类
Throwable 为顶层父类,Throwable派生了Error和Exception类
-
error(错误):例如java语句少了封号,错误不能通过代码处理。
-
Exception(异常):例如
java.lang.ArithmeticException: / by zero
可以用代码处理。
根据javac在编译时候是否进行检查分为下面两种
-
Unckecked Exception(非检查异常)
-
Checked Exception(检查异常)
类异常的结构图
处理异常
try…catch捕获异常
try {
//程序块
} catch (Exception e) {
//Catch捕获异常信息
}finally{
//必须执行的代码
}
throws/throw抛出与异常
public void test1() throws IOException {
File file=new File("./one.txt");
FileReader fileReader=new FileReader(file);
BufferedReader bufferedReader=new BufferedReader(fileReader);
throw new IOException();
}
SpringBoot 全局处理异常
创建响应枚举类
- ResultEnum类:定义返回码的枚举类
/**
* 定义返回码的枚举类
*/
public enum ResultEnum {
//状态码
private Integer code;
//信息
private String message;
//返回结果
private Object data="";
public ResponseInfo() {
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public ResponseInfo(Integer code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
public static ResponseInfo sucess(boolean istrue,String message,Object object){
ResponseInfo responseInfo=new ResponseInfo();
responseInfo.setCode(200);
responseInfo.setMessage(message);
responseInfo.setData(object);
return responseInfo;
}
//失败抛出异常
public static void faild(Exception e){
new Exception(e);
}
}
创建返回信息实体类
- ResponseInfo 返回实体类
public class ResponseInfo {
//状态码
private Integer code;
//信息
private String message;
//返回结果
private Object data="";
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
创建自定义异常类
- MyException
public class MyException extends RuntimeException {
public MyException() {
}
public MyException(String message) {
super(message);
}
public MyException(String message, Throwable cause) {
super(message, cause);
}
public MyException(Throwable cause) {
super(cause);
}
public MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
- NotFountResourceException
public class NotFountResourceException extends RuntimeException{
public NotFountResourceException() {
}
public NotFountResourceException(String message) {
super(message);
}
public NotFountResourceException(String message, Throwable cause) {
super(message, cause);
}
public NotFountResourceException(Throwable cause) {
super(cause);
}
public NotFountResourceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
创建异常处理器
- GlobalExceptionHandler 全局异常处理器
//@RestControllerAdvice代替@ControllerAdvice,这样在方法上就可以不需要添加@ResponseBody
@RestControllerAdvice(basePackages = "com.li")
public class GlobalExceptionHandler {
/**
* 全局异常处理器
* @param e Exception
* @return ResponseInfo
*/
@ResponseBody
@ExceptionHandler(Exception.class)
public ResponseInfo globleExceptionHandler(Exception e, HttpServletResponse response) {
ResponseInfo responseInfo = new ResponseInfo();
// 判断是否为 MyException 异常
if (e instanceof MyException) {
// 设置 HTTP 状态码
response.setStatus(HttpStatus.BAD_REQUEST.value());
// 返回错误信息
responseInfo.setCode(ResultEnum.PARAMETER_ERROR.getCode());
responseInfo.setMessage(e.getMessage());
return responseInfo;
}
// 判断是否为 NotFountResourceException 异常
else if (e instanceof NotFountResourceException) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
responseInfo.setCode(ResultEnum.NOT_FOUNT_RESOURCE.getCode());
responseInfo.setMessage(e.getMessage());
return responseInfo;
}
// 判断是否为丢失请求参数异常
else if (e instanceof MissingServletRequestParameterException) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
responseInfo.setCode(ResultEnum.PARAMETER_MISSING_ERROR.getCode());
responseInfo.setMessage(ResultEnum.PARAMETER_MISSING_ERROR.getMessage());
return responseInfo;
}
// 判断是否为请求参数错误异常
else if (e instanceof MethodArgumentNotValidException) {
response.setStatus(HttpStatus.BAD_REQUEST.value());
responseInfo.setCode(ResultEnum.PARAMETER_ERROR.getCode());
responseInfo.setMessage(ResultEnum.PARAMETER_ERROR.getMessage());
return responseInfo;
}
else if(e instanceof NullPointerException){
response.setStatus(HttpStatus.OK.value());
responseInfo.setCode(ResultEnum.NULL_POINTER.getCode());
responseInfo.setMessage(ResultEnum.NULL_POINTER.getMessage());
return responseInfo;
}
// 不知道异常原因,默认返回未知异常
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
responseInfo.setCode(ResultEnum.UNKNOWN_ERROR.getCode());
responseInfo.setMessage(ResultEnum.UNKNOWN_ERROR.getMessage());
return responseInfo;
}
}
- 404、500处理器
@RestController
public class ErrorHandler implements ErrorController {
@Override
public String getErrorPath() {
return "/error";
}
@GetMapping("/error")
@ResponseStatus(code = HttpStatus.NOT_FOUND)
public ResponseInfo handleError(HttpServletRequest request) {
ResponseInfo responseInfo = new ResponseInfo();
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
// 如果等于 404 错误,则抛出设定的枚举类中的错误信息
if (HttpStatus.NOT_FOUND.value() == statusCode) {
responseInfo.setMessage(ResultEnum.NOT_FOUNT_RESOURCE.getMessage());
responseInfo.setCode(ResultEnum.NOT_FOUNT_RESOURCE.getCode());
return responseInfo;
}
// 如果非404,那就是500错误,则抛出设定的枚举类中的系统错误信息
responseInfo.setMessage(ResultEnum.SYSTEM_ERROR.getMessage());
responseInfo.setCode(ResultEnum.SYSTEM_ERROR.getCode());
return responseInfo;
}
}
测试Controller
@RestController
public class TestController {
/**
* 正常接口
*/
@GetMapping("/normal")
public ResponseInfo normal() {
String data = "模拟的响应数据";
ResponseInfo responseInfo = new ResponseInfo();
responseInfo.setCode(200);
responseInfo.setMessage("请求成功");
responseInfo.setData(new ArrayList<>());
return responseInfo;
}
/**
* 抛出自定义不能发行资源异常,测试自定义无法发现资源异常处理器
*/
@GetMapping("/rsexception")
public String createException() throws NotFountResourceException {
throw new NotFountResourceException("NullPointerException 空指针异常信息");
}
/**
* 抛出自定义异常,测试自定义异常处理器
*/
@GetMapping("/myexception")
public String createMyException() throws MyException {
throw new MyException("MyException 自定义异常信息");
}
/**
* 抛出空指针异常,测试全局异常处理器
*/
@GetMapping("/exception")
public String createGlobleException() {
throw new NullPointerException("NullPointerException 空指针异常信息");
}
}