Springboot项目的@ControllerAdvice实现异常全局自定义处理及返回
一、@ControllerAdvice注解
@ControllerAdvice注解是Spring Framework中的一个注解,用于定义全局异常处理器。当你使用@ControllerAdvice注解标记一个类时,它将成为一个全局异常处理器,适用于你的Spring应用中所有使用了@Controller注解的类。这意味着你可以将异常处理逻辑集中到一个位置,而不是分散到多个控制器中。
二、主要代码
1.设计统一返回Result类及返回状态码枚举(示例)
package com.des.data.common;
import com.des.data.enums.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 全局统一返回结果类
*/
@Data
@ApiModel(value = "全局统一返回结果")
public class Result<T> {
@ApiModelProperty(value = "返回码")
private Integer code;
@ApiModelProperty(value = "返回消息")
private String message;
@ApiModelProperty(value = "返回数据")
private T data;
public Result() {}
public Result(Object parseObject) {}
protected static <T> Result<T> build(T data) {
Result<T> result = new Result<T>();
if (data != null) {
result.setData(data);
}
return result;
}
public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
Result<T> result = build(body);
result.setCode(resultCodeEnum.getCode());
result.setMessage(resultCodeEnum.getMsg());
return result;
}
public static <T> Result<T> build(Integer code, String message) {
Result<T> result = build(null);
result.setCode(code);
result.setMessage(message);
return result;
}
public static <T> Result<T> ok() {
return Result.ok(null);
}
/**
* 操作成功
*
* @param data
* @param <T>
* @return
*/
public static <T> Result<T> ok(T data) {
return build(data, ResultCodeEnum.SUCCESS);
}
public static <T> Result<T> fail() {
return Result.fail(null);
}
/**
* 操作失败
*
* @param data
* @param <T>
* @return
*/
public static <T> Result<T> fail(T data) {
Result<T> result = build(data);
return build(data, ResultCodeEnum.FAILD);
}
public Result<T> message(String msg) {
this.setMessage(msg);
return this;
}
public Result<T> code(Integer code) {
this.setCode(code);
return this;
}
public boolean isOk() {
if (this.getCode().intValue() == ResultCodeEnum.SUCCESS.getCode().intValue()) {
return true;
}
return false;
}
}
package com.des.data.enums;
public enum ResultCodeEnum {
SUCCESS(0, "成功"),
FAILD(-1, "失败");//枚举类如果写方法的话,此处需要写分号
private Integer code;
private String msg;
ResultCodeEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
public static ResultCodeEnum statOf(Integer code) {
for (ResultCodeEnum state : values())
if (state.getCode().equals(code))
return state;
return null;
}
}
2.自定义异常类
自定义异常继承自RuntimeException
package com.des.data.exception.exception;
import com.des.data.enums.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@Data
@ApiModel(value = "自定义全局异常类")//Swagger注解
public class BizSystemException extends RuntimeException{
private Integer code;
private String message;
/**
* 通过状态码和错误消息创建异常对象
*
* @param message
* @param code
*/
public BizSystemException(Integer code, String message) {
super(message);
this.message=message;
this.code = code;
}
public BizSystemException(String message) {
super(message);
this.message=message;
this.code = -1;
}
/**
* 接收枚举类型对象
*
* @param resultCodeEnum
*/
public BizSystemException(ResultCodeEnum resultCodeEnum) {
super(resultCodeEnum.getMsg());
this.code = resultCodeEnum.getCode();
}
@Override
public String toString() {
return "CustomException{" +
"code=" + code +
", message=" + this.getMessage() +
'}';
}
}
3.定义统一异常处理器
package com.des.data.exception;
import com.des.data.common.Result;
import com.des.data.exception.exception.BizSystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GloableExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GloableExceptionHandler.class);
/**
* 拦截其他运行时异常
*/
@ResponseBody
@ExceptionHandler(RuntimeException.class)
public Result handlerRuntimeException(RuntimeException e) {
log.error("[invoke] 运行时异常:", e);
return Result.fail("[invoke] 运行时异常:" + e.getMessage());
}
/**
* 拦截业务异常
*/
@ResponseBody
@ExceptionHandler(BizSystemException.class)
public Result handlerBizException(BizSystemException e) {
log.error("[BizSystemException] 业务异常:", e);
return Result.build(e.getCode(),"[BizSystemException] 业务异常:" + e.getMessage());
}
}
使用举例
package com.des.data.controller;
import com.des.data.common.Result;
import com.des.data.exception.exception.BizSystemException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("data/")
public class RateLimteController {
@PostMapping("invoke")
public Result invoke(){
System.out.println(new Date());
throw new BizSystemException(12000,"业务异常捕获测试");
// return Result.ok();
}
}
输出:
{
"code": 12000,
"message": "[BizSystemException] 业务异常:业务异常捕获测试",
"data": null,
"ok": false
}