Lison <cundream@163.com>
, v1.0.0, 2019.10.13
SpringBoot系统搭建集成-008-捕获全局异常
为了统一api的返回格式,方便前端接受返回数据,全局异常处理是个比较重要的功能,一般在项目里都会用到。
Springboot中的异常捕获通常分为三个阶段。
一:在进入Controller之前,如果请求一个不存在的地址,404错误等
@RestController
@RequestMapping("/error")
@Api(value = "ErrorController", tags = "error", description = "异常处理测试接口")
public class ErrorController extends BaseController {
@RequestMapping(value = "/error")
@ResponseBody
public ResponseWrapper<String> error(HttpServletResponse resp, HttpServletRequest req) {
// 错误处理逻辑
return ResponseWrapperMapper.wrap(ResponseWrapper.NOT_FOUND_CODE);
}
ResponseWrapper 为自定义封装实体类,可根据自己需要设置自己的返回类型
二:在执行@RequestMapping时,进入逻辑处理阶段前。譬如传的参数类型错误。
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler{
/**
* 在controller里面内容执行之前,校验一些参数不匹配啊,Get post方法不对啊之类的
*/
@Override
protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
return ResponseWrapperMapper.wrap(ResponseWrapper.NOT_FOUND_CODE);
}
}
三:以上都正常时,在controller里执行逻辑代码时出的异常。譬如NullPointerException 、数据异常SQLException等等
/**
* @author : Lison
* @Date: 2019/10/16 17:30
* @Description: 全局的的异常拦截器
*/
@Slf4j
@RestControllerAdvice(basePackages = "com.github.cundream")
public class GlobalExceptionHandler {
@Value("${spring.application.name}")
String applicationName;
@Value("${spring.profiles.active}")
String profileActive;
/**
* 非法参数异常.
*
* @param e the e
* @return the wrapper
*/
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseWrapper illegalArgumentException(IllegalArgumentException e) {
String message = ExceptionUtil.getFriendlyErrorMsg(e, "非法参数", applicationName, profileActive);
log.error(message);
return ResponseWrapperMapper.error("参数异常");
}
/**
* 空指针异常.
*
* @param e the e
* @return the wrapper
*/
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseWrapper nullPointerException(NullPointerException e) {
String message = ExceptionUtil.getFriendlyErrorMsg(e, "空指针", applicationName, profileActive);
log.error(message);
return ResponseWrapperMapper.error("系统空指针异常");
}
/**
* 非法状态异常.
*
* @param e the e
* @return the wrapper
*/
@ExceptionHandler(IllegalStateException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseWrapper illegalStateException(IllegalStateException e) {
String message = ExceptionUtil.getFriendlyErrorMsg(e, "非法状态", applicationName, profileActive);
log.error(message);
return ResponseWrapperMapper.error("非法状态");
}
/**
* 索引越界异常.
*
* @param e the e
* @return the wrapper
*/
@ExceptionHandler(IndexOutOfBoundsException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseWrapper indexOutOfBoundsException(IndexOutOfBoundsException e) {
String message = ExceptionUtil.getFriendlyErrorMsg(e, "索引越界", applicationName, profileActive);
log.error(message);
return ResponseWrapperMapper.error("索引越界异常");
}
/**
* 系统异常.
*
* @param e the e
* @return the wrapper
*/
@ExceptionHandler(SystemException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseWrapper systemException(SystemException e) {
String message = ExceptionUtil.getFriendlyErrorMsg(e, "系统", applicationName, profileActive);
log.error(message);
return ResponseWrapperMapper.wrap(e.getCode() == 0 ? ResponseWrapper.ERROR_CODE : e.getCode(), "系统未知错误,修复中");
}
/**
* 业务异常.
*
* @param e the e
* @return the wrapper
*/
@ExceptionHandler(BusinessException.class)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public ResponseWrapper businessException(BusinessException e) {
String message = ExceptionUtil.getFriendlyErrorMsg(e, "业务", applicationName, profileActive);
log.error(message);
return ResponseWrapperMapper.wrap(e.getCode() == 0 ? ResponseWrapper.ERROR_CODE : e.getCode(), e.getMessage());
}
/**
* 全局异常.
*
* @param e the e
* @return the wrapper
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ResponseWrapper exception(Exception e) {
String message = ExceptionUtil.getFriendlyErrorMsg(e, "全局", applicationName, profileActive);
log.error(message);
return ResponseWrapperMapper.error("服务器繁忙.....");
}
/**
* mysql数据库异常.
*
* @param e the e
* @return the wrapper
*/
@ExceptionHandler(SQLException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ResponseWrapper exception(SQLException e) {
String message = ExceptionUtil.getFriendlyErrorMsg(e, "数据库异常", applicationName, profileActive);
log.error(message);
return ResponseWrapperMapper.error("操作失败,数据异常");
}
}
其中BusinessException,SystemException是我自己定义的异常类,可以直接使用基类Exception
{
"code": 404,
"message": null,
"data": null,
"timestamp": "2019-10-17 14:09:57.044"
}
{
"code": 500,
"message": "服务器繁忙.....",
"data": null,
"timestamp": "2019-10-17 14:12:00.872"
}