SpringBoot中全局的异常处理
1.相关的注解
-
@ControllerAdvice
-
@ExceptionHandler
-
@ResponseStatus
2.通用模板
- 定义缺少请求参数异常的方法
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
private static final Logger logger =
LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 缺少请求参数异常
* @param ex HttpMessageNotReadableException
* @return
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public JsonResult handleHttpMessageNotReadableException(
MissingServletRequestParameterException ex) {
logger.error("缺少请求参数,{}", ex.getMessage());
return new JsonResult("400", "缺少必要的请求参数");
}
}
- 定义处理空指针异常的方法
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
private static final Logger logger =
LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 空指针异常
* @param ex NullPointerException
* @return
*/
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public JsonResult handleTypeMismatchException(NullPointerException ex) {
logger.error("空指针异常,{}", ex.getMessage());
return new JsonResult("500", "空指针异常了");
}
}
- 通用模板
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
private static final Logger logger =
LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 系统异常 预期以外异常
* @param ex
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public JsonResult handleUnexpectedServer(Exception ex) {
logger.error("系统异常:", ex);
return new JsonResult("500", "系统发生异常,请联系管理员");
}
}
说明:
但是项目中,我们一般都会比较详细的去拦截一些常见异常,拦截 Exception 虽然可以一劳永逸,但是
不利于我们去排查或者定位问题。实际项目中,可以把拦截 Exception 异常写在
GlobalExceptionHandler 最下面,如果都没有找到,最后再拦截一下 Exception 异常,保证输出信息
友好。
3.拦截自定义异常
3.1 定义异常信息
说明:
为了方便管理异常信息,我们一般会定义一个异常信息枚举类
一般参照网上的课程,大部分异常信息都是用枚举类进行管理,特点就是方便,解耦
/**
* 业务异常提示信息枚举类
* @author shengwu ni
*/
public enum BusinessMsgEnum {
/** 参数异常 */
PARMETER_EXCEPTION("102", "参数异常!"),
/** 等待超时 */
SERVICE_TIME_OUT("103", "服务调用超时!"),
/** 参数过大 */
PARMETER_BIG_EXCEPTION("102", "输入的图片数量不能超过50张!"),
/** 500 : 一劳永逸的提示也可以在这定义 */
UNEXPECTED_EXCEPTION("500", "系统发生异常,请联系管理员!");
// 还可以定义更多的业务异常
/**
* 消息码
*/
private String code;
/**
* 消息内容
*/
private String msg;
private BusinessMsgEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
// set get方法
}
3.2定义自定义异常
/**
* 自定义业务异常
* @author shaoming
*/
public class BusinessErrorException extends RuntimeException {
private static final long serialVersionUID = -7480022450501760611L;
/**
* 异常码
*/
private String code;
/**
* 异常提示信息
*/
private String message;
public BusinessErrorException(BusinessMsgEnum businessMsgEnum) {
this.code = businessMsgEnum.code();
this.message = businessMsgEnum.msg();
}
// get set方法
}
3.3配置拦截自定义异常
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
private static final Logger logger =
LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 拦截业务异常,返回业务异常信息
* @param ex
* @return
*/
@ExceptionHandler(BusinessErrorException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public JsonResult handleBusinessError(BusinessErrorException ex) {
String code = ex.getCode();
String message = ex.getMessage();
return new JsonResult(code, message);
}
}
3.4 测试处理自定义异常
@RestController
@RequestMapping("/exception")
public class ExceptionController {
private static final Logger logger =
LoggerFactory.getLogger(ExceptionController.class);
@GetMapping("/business")
public JsonResult testException() {
try {
int i = 1 / 0;
} catch (Exception e) {
throw new
BusinessErrorException(BusinessMsgEnum.UNEXPECTED_EXCEPTION);
}
return new JsonResult();
}
}
页面返回
{“code”:“500”,“msg”:“系统发生异常,请联系管理员!”}