在我们进行业务处理时,业务异常是必不可少的,我们会对这些异常进行统一管理,即可美化代码也可方便我们进行异常解析。
使用@ControllerAdvice结合@ExceptionHandler自定义异常,用于全局异常的处理
@ControllerAdvice,Spring注解,可对controller中被@PostMapping、 @GetMapping、@RequestMapping等注解的方法加一些逻辑处理
@ExceptionHandler,Spring注解,可捕获Controller中抛出的不同类型的异常,从而达到异常全局处理的目的
异常处理类
使用@ControllerAdvice注解
/**
* 全局处理controller层
* create by Qs
*/
@ControllerAdvice
public class BusinessExceptionHandler {
static final Log log = LogFactory.getLog(BusinessExceptionHandler.class);
@ResponseBody
@ExceptionHandler(value = {Exception.class})
public ExceptionResponse handleException(Exception ex) {
if (ex instanceof BusinessException) {
BusinessException businessException = (BusinessException) ex;
if(businessException.getCode() == 999){
return ExceptionResponse.create(businessException.getCode(), businessException.getResultJson());
}
return ExceptionResponse.create(businessException.getCode(), businessException.getMessage());
}
// http方法错误
else if (ex instanceof HttpRequestMethodNotSupportedException) {
log.error("",ex);
return ExceptionResponse.create(100, "客户端HTTP请求方法错误:"+ex.getMessage());
}
else if (ex instanceof ServletRequestBindingException){
log.error("",ex);
return ExceptionResponse.create(102, "客户端参数错误:"+ex.getMessage());
}
else{
log.error("",ex);
return ExceptionResponse.create(100, "服务器内部错误:"+ex.getMessage());
}
}
}
自定义异常类
继承RuntimeException
/**
* 自定义异常类
* create by Qs
*/
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 1l;
private Integer code;
private String resultJson;
public BusinessException(ErrorEnum errorEnum) {
super(errorEnum.getErrorMsg());
this.code = errorEnum.getErrorCode();
this.resultJson = JSONObject.toJSONString(errorEnum);
}
public BusinessException(ErrorEnum errorEnum, String errorMsg) {
this.code = errorEnum.getErrorCode();;
this.resultJson = errorMsg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getResultJson() {
return resultJson;
}
public void setResultJson(String resultJson) {
this.resultJson = resultJson;
}
}
响应模板类
/**
* 响应模板类
* create by Qs
*/
public class ExceptionResponse {
private String msg;
private Integer code;
public ExceptionResponse(Integer code, String message) {
this.msg = message;
this.code = code;
}
public static ExceptionResponse create(Integer code, String message) {
return new ExceptionResponse(code, message);
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
错误码枚举类
整合自定义的错误信息
/**
* 错误码
* create by Qs
*/
public enum ErrorEnum {
/*
* 错误信息
* */
ERR_0(0, "ok"),
ERR_999(999, ""),
ERR_401(401, "用户未登录或者登录过期"),
ERR_100(100, "系统异常"),
ERR_101(101, "参数为空"),
ERR_102(102, "参数错误"),
;
private Integer errorCode;
private String errorMsg;
ErrorEnum(Integer errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public Integer getErrorCode() {
return errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorCode(Integer errorCode) {
this.errorCode = errorCode;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}
公共返回类
public class ExceptionResult {
public static ExceptionResponse errorResponse(ErrorEnum errorEnum) {
return ExceptionResponse.create(errorEnum.getErrorCode(),errorEnum.getErrorMsg());
}
public static ExceptionResponse errorResponse(int errcode,String errmsg) {
return ExceptionResponse.create(errcode,errmsg);
}
public static ExceptionResponse errorResponse(String errmsg) {
return ExceptionResponse.create(ErrorEnum.ERR_999.getErrorCode(),errmsg);
}
}
测试一下
@RestController
@RequestMapping("/info")
public class InformationController {
@RequestMapping(value="/getNoticeList",method = RequestMethod.GET)
public Object getNoticeList(@RequestParam Map<String, String> params){
JsonReponse result = new JsonReponse();
String pageNoStr = params.get("page");
String pageSizeStr = params.get("size");
if (CommonUtils.isEmpty(pageNoStr) || CommonUtils.isEmpty(pageSizeStr)){
throw new BusinessException(ErrorEnum.ERR_101);
}
int pageNo = Integer.parseInt(pageNoStr);
int pageSize = Integer.parseInt(pageSizeStr);
if (pageNo <= 0 || pageSize <= 0){
throw new BusinessException(ErrorEnum.ERR_102);
}
return result;
}
}
访问接口
正常访问时,返回我们需要的正常信息
当传递参数错误时,返回的就是我们在ErrorEnum中定义的异常信息
将异常信息throw到controller层,通过@ExceptionHandler进行全局捕获,进行统一处理响应,再通过我们自定义的异常类,得到我们想要的异常信息,最后响应异常信息
一种美而简的异常处理方式