SpringBoot项目通用返回值与全局异常处理

本文介绍如何在SpringBoot项目中实现通用的返回值和全局异常处理,通过定义Result类、异常类及枚举,配合全局异常处理器,提高前后端分离开发效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot项目通用返回值与全局异常处理

目前很多公司开发时候都是前后端分离,后台给前端如果能返回一个统一的格式,统一接口报文格式,开发效率都会大大提升。

定义一个通用返回结果Result类

public class Result<T> {
    private boolean success = true;
    private String errorCode = "0";
    private String errorMsg = null;
    private List<T> data = new ArrayList<>();

    public Result() {
    }

    public Result(List<T> data) {
        if (data != null && data.size() > 0) {
            this.data = data;
        }
    }

    public Result(T data) {
        this.data.add(data);
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Result{" +
                "success=" + success +
                ", errorCode='" + errorCode + '\'' +
                ", errorMsg='" + errorMsg + '\'' +
                ", data=" + data +
                '}';
    }
}

异常类与异常枚举类

public enum MyExceptionEnum {
    REQUESTPARAM_NOTNULL("A001", "请求参数不能为空"),
    SYSTEM_ERROR("-1", "系统异常"),
    DATASOURCE_ERROR("-2", "数据库异常"),
    OTHER_ERROR("-3", "未知异常");

    private String code;
    private String msg;

    MyExceptionEnum(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public static MyExceptionEnum getByCode(String code) {
        if (StringUtils.isEmpty(code)) {
            return null;
        } else {
            MyExceptionEnum[] var1 = values();
            int var2 = var1.length;
            for(int var3 = 0; var3 < var2; ++var3) {
                MyExceptionEnum errorEnum = var1[var3];
                if (errorEnum.getCode().equals(code)) {
                    return errorEnum;
                }
            }
            return null;
        }
    }
}
public class MyException extends RuntimeException{

    private String errorCode;

    private String errorMsg;

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public MyException(String errorCode, String errorMsg) {
        super(errorMsg);
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public MyException(String errorCode, String errorMsg, String description) {
        super(errorMsg + description);
        this.errorCode = errorCode;
        this.errorMsg = errorMsg + description;
    }

    public MyException(MyExceptionEnum myExceptionEnum) {
        super(myExceptionEnum.getMsg());
        this.errorCode = myExceptionEnum.getCode();
        this.errorMsg = myExceptionEnum.getMsg();
    }

    public MyException(MyExceptionEnum myExceptionEnum, String description) {
        super(myExceptionEnum.getMsg() + description);
        this.errorCode = myExceptionEnum.getCode();
        this.errorMsg = myExceptionEnum.getMsg() + description;
    }
}

全局异常处理

@RestControllerAdvice
public class MyExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @ExceptionHandler(Exception.class)
    public Object handleException(Exception e, HttpServletRequest request, HttpServletResponse response){

        logger.error("请求:{}发生异常:{}", request.getRequestURI(), e);

        Result result = new Result();
        result.setSuccess(false);
        if (e instanceof MyException) {
            result.setErrorCode(((MyException) e).getErrorCode());
            result.setErrorMsg(((MyException) e).getErrorMsg());
        } else {
            result.setErrorCode(MyExceptionEnum.SYSTEM_ERROR.getCode());
            result.setErrorMsg(MyExceptionEnum.SYSTEM_ERROR.getMsg());
        }

        return result;
    }
}

Controller抛出自定义异常

@RequestMapping(
            value = "test",
            method = RequestMethod.POST)
    public FrogTest test(@RequestBody FrogTest bean) {
        if (bean.getName()  == null) {
            throw new MyException(MyExceptionEnum.REQUESTPARAM_NOTNULL);
        }
        int i = 10/0;
        return bean;
    }

测试
请求bean中name不为null时,返回前端

{
    "success": false,
    "errorCode": "-1",
    "errorMsg": "系统异常",
    "data": []
}

查看日志信息

2018-09-21 10:57:10.041 ERROR 7460 --- [io-10050-exec-3] c.f.m.common.MyExceptionHandler          : 请求:/frog-test/test发生异常:{}

java.lang.ArithmeticException: / by zero
	at com.frog.mybatisplus.controller.FrogTestController.test(FrogTestController.java:77) ~[classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_152]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_152]
	...

请求bean中name为null时

{
    "success": false,
    "errorCode": "A001",
    "errorMsg": "请求参数不能为空",
    "data": []
}
### Java 中全局 Null 值处理的最佳实践 在 Java 开发中,`null` 是一个特殊值,表示引用变量未指向任何对象。不当的 `null` 使用可能导致运行时错误,尤其是 `NullPointerException`。为了减少这类问题的发生并提高代码质量,在项目中实现全局 `null` 检查是一种有效的策略。 以下是几种推荐的全局 `null` 处理方法及其最佳实践: #### 1. **使用断言机制** 通过引入断言来验证参数是否为 `null`,可以在早期发现潜在问题。这种方式适用于开发阶段调试程序。 ```java public void process(String input) { Objects.requireNonNull(input, "Input cannot be null"); } ``` 这种方法利用了 `Objects.requireNonNull` 方法[^3],能够快速检测传入的对象是否为空,并抛出自定义消息的异常。 #### 2. **采用 Optional 类型** 自 Java 8 起,`Optional<T>` 提供了一种优雅的方式来表达可能不存在的值,从而避免显式的 `null` 判断。 ```java import java.util.Optional; public class Example { public static String getName() { return null; } public static void main(String[] args) { Optional<String> name = Optional.ofNullable(getName()); name.ifPresentOrElse( value -> System.out.println("Name is present: " + value), () -> System.out.println("No name provided.") ); } } ``` 此方式不仅减少了直接操作 `null` 的风险,还增强了代码可读性和安全性。 #### 3. **设置默认值替代 null** 对于某些场景下允许存在缺省行为的情况,可以考虑提供合理的默认值代替可能出现的 `null` 返回值。 ```java public String getUserRole(User user){ return (user != null && user.getRoles() != null)? user.getRoles().get(0): "Guest"; } ``` #### 4. **应用 AOP 面向切面编程技术** 如果希望在整个应用程序范围内统一管理 `null` 检测逻辑,则可以通过 Spring Framework 或其他支持 AOP 技术框架创建环绕通知(Around Advice),自动拦截目标方法调用前后的状态变化情况。 ```java @Aspect @Component public class NullCheckAspect { @Before("@annotation(com.example.annotations.NotNull)") public void checkForNullArguments(JoinPoint joinPoint) throws Throwable{ Arrays.stream(joinPoint.getArgs()).forEach(arg->{ if(arg==null){ throw new IllegalArgumentException("Argument can't be null."); } }); } } ``` 上述例子展示了如何借助注解驱动的方式强制执行输入校验规则[^1]。 #### 5. **编写工具函数封装公共逻辑** 当多个地方都需要重复相同的非空判断流程时,建议提取成独立的方法或者类库形式加以复用。 ```java public final class ValidationUtils { private ValidationUtils(){} public static <T> T validateNotNull(T object,String message){ if(object == null){ throw new NullPointerException(message); } return object; } } // Usage example: ValidationUtils.validateNotNull(user,"User instance must not be null!"); ``` 综上所述,以上提到的各种手段各有优劣之处,实际选用需依据具体业务需求权衡利弊决定最合适的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值