我跟着黑马老师写了一个spring-boot异常处理器,但是不知道里面写的是些什么东西,下面写一篇文章记录一下spring-boot异常处理器应该怎么些。
为什么些异常处理器
我觉得写异常处理器的作用就是给前端返回可以理解的信息,因为有些异常如果没有被处理,那么给前端返回的都是一些不好理解的东西,比如下面的参数校验异常:
// 管理员登录
@PostMapping("/login")
public Result<Void> login(
@RequestParam
@NotBlank(message = "用户名不能为空")
String username,
@RequestParam
@NotBlank(message = "密码不能为空")
String password) {
boolean result = adminService.loginAdmin(username, password);
if (!result) {
return Result.error("用户名或密码错误!");
}
return Result.success("登录成功!");
}
如果没有异常处理器,然后前端传递的参数有问题,给前端返回的是这样的信息:
{
"timestamp": "2025-02-03T01:38:41.245+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/admin/login"
}
如果有异常处理器,给前端返回的是这样的信息:
{
"code": 0,
"msg": "login.password: 密码不能为空",
"data": null
}
代码结构
首先我们创建一个exception包:
然后异常处理类的代码是这样的:
package com.akbar.exception;
import com.akbar.util.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
// 创建日志记录器
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
// 处理全局异常
@ExceptionHandler(Exception.class)
public Result<Void> handleException(Exception e) {
// 错误输出到控制台
LOGGER.error("全局异常捕获", e);
return Result.error(StringUtils.hasLength(e.getMessage())? e.getMessage() : "操作失败!");
}
}
代码中我使用logback打印了错误日志,当然也可以直接使用System.out.println()来打印。
logback依赖引入:
<!--日志,springboot默认使用logback-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
理解异常处理器
@RestControllerAdvice
这个注解是@ControllerAdvice和@ResponseBody的组合,表示这是一个控制器增强类,用于处理全局的异常。它不仅可以处理异常,还可以提供统一的响应格式。@ResponseBody确保返回的结果会被自动序列化成JSON格式,因此返回的Result对象会自动转化为JSON。
@ExceptionHandler
@ExceptionHandler注解表示这个方法用来处理Exception类型的异常。你可以在这里指定处理的异常类型,Spring会捕获该类型及其子类型的异常。在代码中我们捕获了Exception.class,意味着所有未被其他处理器处理的异常都会通过这个方法来处理。