java全局异常捕捉_Java全局异常捕捉

1.场景还原

在项目开发中,对于各种异常都有不同的报错提示或策略,无疑对于用户或者开发来说,是一个很好的用户体验;如何在java定义一个全局异常捕捉呢?

2.实现方案

2.1 自定义一个业务异常类

@Setter

@Getter

public class BizException extends RuntimeException {

private static final long serialVersionUID = -6233506444097954612L;

/**

* 错误码

*/

private String errorCode;

/**

* 错误信息

*/

private String errorMsg;

/**

* 返回错误对象信息

*/

private Object data;

public BizException() {

super();

}

public BizException(String errorMsg) {

super(errorMsg);

this.errorMsg = errorMsg;

}

public BizException(String errorCode, String errorMsg) {

super(errorCode);

this.errorCode = errorCode;

this.errorMsg = errorMsg;

}

public BizException(String errorCode, String errorMsg, Throwable cause) {

super(errorCode, cause);

this.errorCode = errorCode;

this.errorMsg = errorMsg;

}

public BizException(ResultEnum resultEnum) {

super(resultEnum.code());

this.errorCode = resultEnum.code();

this.errorMsg = resultEnum.message();

}

public BizException(ResultEnum resultEnum, Throwable cause) {

super(resultEnum.code(), cause);

this.errorCode = resultEnum.code();

this.errorMsg = resultEnum.message();

}

public BizException(ResultEnum resultEnum, Object data) {

this.errorCode = resultEnum.code();

this.errorMsg = resultEnum.message();

this.data = data;

}

}

2.2 定义一个错误枚举类

public enum ResultEnum {

SUCCESS("200", "success"),

FAIL("0", "failed"),

PARAM_INVALID("-1", "param is invalid");

private String code;

private String message;

ResultEnum(String code, String message){

this.code = code;

this.message = message;

}

public String code(){

return this.code;

}

public String message(){

return this.message;

}

}

2.3 定义一个全局异常捕捉类

@Slf4j

@ResponseBody

@ControllerAdvice

public class GlobalExceptionHandler {

/**

* 处理自定义的业务异常

*

* @param e

* @return

*/

@ExceptionHandler(value = BizException.class)

public RestResponse bizExceptionHandler(BizException e) {

log.error("业务异常!原因:{}", e.getErrorMsg());

return RestResponse.fail(e.getErrorCode(), e.getErrorMsg());

}

/**

* 处理空指针的异常

*

* @param e

* @return

*/

@ExceptionHandler(value = NullPointerException.class)

public RestResponse exceptionHandler(NullPointerException e) {

log.error("空指针异常!原因:{}", e);

return RestResponse.fail("空指针异常");

}

@ExceptionHandler(value = Exception.class)

@ResponseBody

public RestResponse exceptionHandler(Exception e) {

StringBuilder errMsg = new StringBuilder();

// 方法参数无效 异常

if (e instanceof MethodArgumentNotValidException) {

BindingResult bindResult = ((MethodArgumentNotValidException) e).getBindingResult();

ListfieldErrorList = bindResult.getFieldErrors();

fieldErrorList.forEach(fieldErrors -> {

if (StringUtils.isNotBlank(errMsg.toString())) {

errMsg.append(",");

}

errMsg.append(fieldErrors.getDefaultMessage());

}

);

} else {

return RestResponse.fail(ResultEnum.INTERNAL_ERROR);

}

return RestResponse.fail(errMsg.toString());

}

}

2.4 定义一个restful response类

@Setter

@Getter

public class RestResponse {

private String code;

private String message;

private Object data;

public RestResponse(){

}

public static RestResponse success(){

RestResponse restResponse = new RestResponse();

restResponse.setResultCode(ResultEnum.SUCCESS);

return restResponse;

}

public static RestResponse success(Object data){

RestResponse restResponse = new RestResponse();

restResponse.setResultCode(ResultEnum.SUCCESS);

restResponse.setData(data);

return restResponse;

}

public static RestResponse fail() {

RestResponse restResponse = new RestResponse();

restResponse.setResultCode(ResultEnum.FAIL);

return restResponse;

}

public static RestResponse fail(ResultEnum resultEnum) {

RestResponse restResponse = new RestResponse();

restResponse.setResultCode(resultEnum);

return restResponse;

}

public static RestResponse fail(String message) {

RestResponse restResponse = new RestResponse();

restResponse.setCode(ResultEnum.FAIL.code());

restResponse.setMessage(message);

return restResponse;

}

public static RestResponse fail(String code, String message) {

RestResponse restResponse = new RestResponse();

restResponse.setCode(code);

restResponse.setMessage(message);

return restResponse;

}

public static RestResponse fail(ResultEnum resultEnum, Object data) {

RestResponse restResponse = new RestResponse();

restResponse.setResultCode(resultEnum);

restResponse.setData(data);

return restResponse;

}

private void setResultCode(ResultEnum resultEnum){

this.code = resultEnum.code();

this.message = resultEnum.message();

}

}

2.5 从service或controller抛出具体异常

@GetMapping("/getInfo")

@ApiOperation(value = "get user info api")

public RestResponse getUserInfo(HttpServletRequest request) {

return RestResponse.fail(ResultEnum.USER_NOY_EXISTS);

}

本文主要@ControllerAdvice+@ExceptionHandler两个注解结合实现全局异常捕捉,对于两个注解的原理,有兴趣的同学可以去研究下底层是怎么工作的,我这里就不再赘述!


版权声明:本文为weixin_30529479原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。