📅  最后修改于: 2023-12-03 15:20:12.968000             🧑  作者: Mango
在 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 异常处理是一个非常重要的功能,掌握好异常处理的基本方式和常用技巧,可以让我们更加优雅地处理项目中的异常情况,提高代码的可读性和鲁棒性。