📜  Spring Boot-异常处理(1)

📅  最后修改于: 2023-12-03 15:20:12.968000             🧑  作者: Mango

Spring Boot 异常处理

在 Web 开发中,无论是前后端交互还是服务接口调用,都难免会遇到各种异常。如何在 Spring Boot 项目中优雅地处理这些异常,是一个程序员需要掌握的重要技能。

定义异常

在 Spring Boot 中,定义异常通常需要继承 RuntimeException 或者 Exception,具体使用哪个取决于异常的功能和作用。

public class MyException extends RuntimeException {
    public MyException(String message) {
        super(message);
    }
}

public class MyCheckedException extends Exception {
    public MyCheckedException(String message) {
        super(message);
    }
}
异常处理

Spring Boot 提供了两种方式来实现异常处理:全局异常处理和精确异常处理。

全局异常处理

全局异常处理可以捕获项目中所有未被精确捕获的异常,进行统一处理。

定义全局异常处理器

通过 @ControllerAdvice 和 @ExceptionHandler 注解即可定义一个全局异常处理器。

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MyException.class)
    @ResponseBody
    public Result handleMyException(MyException e) {
        return ResultUtils.error(e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result handleException(Exception e) {
        return ResultUtils.error("系统错误,请联系管理员");
    }
}

定义返回结果

返回结果通常包含三个字段:状态码、消息和数据。其中,状态码为 0 表示成功,为其他值表示失败。消息用于描述异常信息。数据包含异常数据或者业务数据。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {

    private Integer code;
    private String message;
    private T data;

    public static <T> Result<T> success(T data) {
        return new Result<>(0, "成功", data);
    }

    public static Result<Void> error(String message) {
        return new Result<>(1, message, null);
    }
}

统一返回格式

通过 Spring Boot 自带的 ResponseEntity 和 ResponseBodyAdvice 可以实现全局返回格式的统一和封装。

@ControllerAdvice
public class GlobalControllerAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest,
                                  ServerHttpResponse serverHttpResponse) {
        if (body instanceof Result) {
            return body;
        }
        return ResultUtils.success(body);
    }
}
精确异常处理

精确异常处理可以针对具体的异常类型进行处理。

抛出异常

在业务逻辑处理的过程中,如果发生特定的异常,就可以抛出这个异常。Spring Boot 会自动处理异常并返回指定的错误信息。

public void updateUser(User user) {
    if (user.getId() == null) {
        throw new IllegalArgumentException("用户ID不能为空");
    }
    userDao.update(user);
}

异常处理器

精确异常处理器需要使用 @ExceptionHandler 进行定义,这里只需要针对特定的异常进行处理即可。

@ControllerAdvice
public class UserControllerAdvice {

    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseBody
    public Result handleIllegalArgumentException(IllegalArgumentException e) {
        return ResultUtils.error(e.getMessage());
    }
}
获取异常信息

当出现异常时,我们需要获取一些异常信息,例如堆栈信息、异常类型和异常消息等。

默认错误处理机制

Spring Boot 默认的错误处理机制会返回异常信息和 HTTP 状态码。

{
    "timestamp": "2021-06-29T05:03:38.619+0000",
    "status": 500,
    "error": "Internal Server Error",
    "path": "/users"
}
自定义错误处理机制

为了获取更加详细的异常信息,可以通过 @ExceptionHandler 和 @ControllerAdvice 自定义错误处理机制。

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MyException.class)
    @ResponseBody
    public Result handleMyException(MyException e) {
        return ResultUtils.error(e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result handleException(Exception e) {
        return ResultUtils.error(MessageUtils.getMessage("sys.error"));
    }

    @ModelAttribute
    public void addAttributes(Model model) {
        model.addAttribute("author", "Java编程思想");
    }
}

其中,@ModelAttribute 注解可以在结果中添加指定的属性。通常可以添加作者、版本号等信息。

总结

Spring Boot 异常处理是一个非常重要的功能,掌握好异常处理的基本方式和常用技巧,可以让我们更加优雅地处理项目中的异常情况,提高代码的可读性和鲁棒性。