当前位置: 首页 > news >正文

全局异常处理器的基本使用

那使用全局异常处理器可以么?

是的,使用全局异常处理器是一个非常好的选择,因为它可以将异常处理逻辑集中化,避免在 Service 层或 Controller 层中重复编写异常处理代码。以下是使用全局异常处理器来处理添加用户时 username 唯一约束冲突的完整实现方案:


1. 全局异常处理器的优势

  • 集中管理:所有异常处理逻辑集中在一个地方,便于维护和扩展。
  • 代码简洁Service 层和 Controller 层只需关注业务逻辑,不需要处理异常。
  • 统一响应格式:可以确保所有异常返回的响应格式一致,提升 API 的规范性。

2. 实现步骤

步骤 1:定义自定义异常

为了更好地区分业务异常,可以定义一个自定义异常类。

java

换行复制代码

1public class BusinessException extends RuntimeException {
2    public BusinessException(String message) {
3        super(message);
4    }
5}

步骤 2:在 Service 层抛出异常

在 UserService 层中,如果检测到 username 已存在,抛出 BusinessException

java

换行复制代码

1import org.springframework.beans.factory.annotation.Autowired;
2import org.springframework.dao.DuplicateKeyException;
3import org.springframework.stereotype.Service;
4
5@Service
6public class UserServiceImpl implements UserService {
7
8    @Autowired
9    private UserMapper userMapper;
10
11    @Override
12    public void addUser(User user) {
13        try {
14            int affectedRows = userMapper.addOneUser(user);
15            if (affectedRows != 1) {
16                throw new RuntimeException("添加用户失败,影响行数为 " + affectedRows);
17            }
18        } catch (DuplicateKeyException e) {
19            // 捕获唯一约束异常
20            throw new BusinessException("用户名已存在");
21        }
22    }
23}

步骤 3:实现全局异常处理器

使用 @ControllerAdvice 和 @ExceptionHandler 注解,创建一个全局异常处理器,统一处理 BusinessException 和其他异常。

java

换行复制代码

1import org.springframework.http.HttpStatus;
2import org.springframework.http.ResponseEntity;
3import org.springframework.web.bind.annotation.ControllerAdvice;
4import org.springframework.web.bind.annotation.ExceptionHandler;
5import org.springframework.web.bind.annotation.ResponseBody;
6
7@ControllerAdvice
8public class GlobalExceptionHandler {
9
10    // 处理自定义业务异常
11    @ExceptionHandler(BusinessException.class)
12    @ResponseBody
13    public ResponseEntity<Map<String, Object>> handleBusinessException(BusinessException e) {
14        Map<String, Object> response = new HashMap<>();
15        response.put("code", 409); // 409 Conflict
16        response.put("message", e.getMessage());
17        return new ResponseEntity<>(response, HttpStatus.CONFLICT);
18    }
19
20    // 处理其他异常
21    @ExceptionHandler(Exception.class)
22    @ResponseBody
23    public ResponseEntity<Map<String, Object>> handleGenericException(Exception e) {
24        Map<String, Object> response = new HashMap<>();
25        response.put("code", 500); // 500 Internal Server Error
26        response.put("message", "系统错误,请稍后重试");
27        return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
28    }
29}

步骤 4:在 Controller 层调用 Service 层

在 Controller 层中,直接调用 UserService 的方法,无需处理异常。

java

换行复制代码

1import org.springframework.beans.factory.annotation.Autowired;
2import org.springframework.http.ResponseEntity;
3import org.springframework.web.bind.annotation.PostMapping;
4import org.springframework.web.bind.annotation.RequestBody;
5import org.springframework.web.bind.annotation.RequestMapping;
6import org.springframework.web.bind.annotation.RestController;
7
8@RestController
9@RequestMapping("/users")
10public class UserController {
11
12    @Autowired
13    private UserService userService;
14
15    @PostMapping
16    public ResponseEntity<String> addUser(@RequestBody User user) {
17        userService.addUser(user);
18        return ResponseEntity.ok("用户添加成功");
19    }
20}

3. 完整流程

  1. Controller 层 调用 UserService 的 addUser 方法。
  2. UserService 层 执行 INSERT 操作:
    • 如果成功,返回 void
    • 如果因为 username 唯一约束失败,抛出 BusinessException
  3. 全局异常处理器 捕获 BusinessException,返回 409 状态码和错误信息。
  4. Controller 层 根据 UserService 的返回值或全局异常处理器的响应,返回最终的 HTTP 响应。

4. 示例响应

添加成功

json

换行复制代码

1{
2    "code": 200,
3    "message": "用户添加成功"
4}
用户名已存在

json

换行复制代码

1{
2    "code": 409,
3    "message": "用户名已存在"
4}
系统错误

json

换行复制代码

1{
2    "code": 500,
3    "message": "系统错误,请稍后重试"
4}

5. 优点

  • 代码简洁Controller 层和 Service 层只需关注业务逻辑,异常处理由全局异常处理器统一管理。
  • 可扩展性强:如果需要处理更多类型的异常,只需在全局异常处理器中添加新的 @ExceptionHandler 方法。
  • 统一响应格式:所有异常返回的响应格式一致,便于前端处理。

6. 注意事项

  • 异常分类:根据业务需求,可以定义更多的自定义异常类(如 ValidationExceptionNotFoundException 等),并在全局异常处理器中分别处理。
  • 日志记录:在全局异常处理器中记录异常日志,便于排查问题。
  • 国际化:如果需要支持多语言,可以在全局异常处理器中根据请求头或用户偏好返回相应的错误信息。

通过这种方式,可以构建一个健壮且易于维护的异常处理机制。

相关文章:

  • JS-防抖与节流
  • 【STM32】解读启动文件startup_stm32f10x_md.s
  • Vue 大文件分片上传组件实现解析
  • 互联网三高-高性能之无锁编程
  • [蓝桥杯 2023 省 A] 平方差
  • CSS高度坍塌?如何解决?
  • 达梦数据库-学习-16-常用SQL记录(持续更新)
  • 【家政平台开发(36)】数据迁移与初始化开发:筑牢家政平台的数据根基
  • JavaScript 代码混淆与反混淆技术详解
  • 构建高可靠C++服务框架:从日志系统到任务调度器的完整实现
  • 定制一款国密浏览器(5):修改浏览器名称
  • Python 关键字详解
  • 超低功耗MCU软件开发设计中的要点与选型推荐
  • 基于SSM的线上花店鲜花销售商城网站系统
  • spark-core编程2
  • 使用Python计算万有引力势能
  • MYOJ_4553:(洛谷P1022)[NOIP 2000 普及组] 计算器的改良(数学运算与求解相关)
  • ubuntu22.04下安装mysql以及mysql-workbench
  • 【2025年认证杯数学中国数学建模网络挑战赛】A题解题思路与模型代码
  • ssh 登录报错集合(FQA)
  • 淘宝网站是怎么做的吗/百度高级搜索页面
  • 成品网站管理系统源码/照片查询百度图片搜索
  • 石家庄网站app开发/上海十大营销策划公司
  • 佛山营销网站建设服务公司/sem竞价广告
  • 硅谷电视剧他们做的是网站还是软件/现在有什么技能培训班
  • 网新科技做网站怎么样/培训计划模板