tulip notes
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Star-Lord

希望一天成为大师的学徒
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 探索SpringBoot

  • 常用功能实现

    • SpringBoot常用功能实现_1
    • SpringBoot中拦截器与日志
    • 多环境配置与数据绑定
    • 异步方法(线程池)的实现
    • controller参数接收
    • SpringBoot中关于日志的更好使用
    • 异常捕获的一些细节
      • SpringBoot中的异常捕获
        • @ControllerAdvice
        • 特点
        • 返回结果
        • @RestControllerAdvice
        • @ExceptionHandler
        • ErrorrController接口
        • 扩展
      • 全局异常处理
        • 注意事项
        • 1.避免重复 `try-catch`
        • 2. 异常类的继承关系
        • 3. 安全性
        • 4.优先级与覆盖
    • 时间跟其他数据的序列化
    • 面向切面跟自定义注解的结合
  • Security认证授权

  • 扩展

  • 实战与注意事项

  • 其它

  • 《SpringBoot》笔记
  • 常用功能实现
EffectTang
2025-05-14
目录

异常捕获的一些细节

# 异常捕获的一些细节

# SpringBoot中的异常捕获

在本地进行开发时,程序运行,它的错误信息默认是打印在控制台的,但实际开发中,我们应该将这些错误信息返回给前端,以便定位问题与修复bug。

因此错误异常的处理十分重要,而错误异常的处理,在编程世界中有一个特殊的名字——异常捕获。

在 Spring Boot 应用中,异常处理是确保系统健壮性和用户体验的重要环节。下面就介绍一些, Spring Boot 中异常捕获和处理的常见方法、注意事项以及关键注解的使用说明。

# @ControllerAdvice

我们可以使用 @ControllerAdvice 搭配@ExceptionHandler实现全局异常处理,只需要定义类,添加该注解即可定义方式如下(或者使用@RestControllerAdvice):

@ControllerAdvice
public class MyGlobalExceptionHandler {

   @ExceptionHandler(ArithmeticException.class)
    public ResultResp customException(ArithmeticException e) {
        System.out.println(e.getMessage());
        return ResultResp.successOf(e.getMessage());
    }
}
1
2
3
4
5
6
7
8
9

解析:@ExceptionHandler 注解用来指明异常的处理类型,即如果这里指定为 NullpointerException,则数组越界异常就不会进到这个方法中来。在该类中,可以定义多个方法,不同的方法处理不同的异常,例如专门处理空指针的方法、专门处理数组越界的方法…,也可以直接在一个方法中处理所有的异常信息。

# 特点

它有以下两个特点

  • 可与 @ExceptionHandler 配合使用,集中处理异常。
  • 可以限定作用范围(例如只处理特定包下的 Controller)。
@ControllerAdvice(basePackages = "com.example.controller")
public class GlobalExceptionHandler {
    // 异常处理方法
}
1
2
3
4

# 返回结果

这种异常的返回结果,通常来说是一个固定的结构。

通常我们用一个结果类,或者枚举类(enum)来进行异常信息的管理,常有字段——code、message

@Data
public class ResultResp<T> {

    private String message;
    private Integer code;
    private Boolean status = true;

    private T data;

    public static ResultResp errorOf(Integer code,String message){
        ResultResp resultResp = new ResultResp();
        resultResp.setStatus(false);
        resultResp.setCode(code);
        resultResp.setMessage(message);
        return resultResp;
    }

    public static <T> ResultResp successOf(T t){
        ResultResp resultResp = new ResultResp();
        resultResp.setCode(200);
        resultResp.setData(t);
        resultResp.setMessage("请求成功");
        return resultResp;
    }

    public static <T> ResultResp isOk(String message,Integer code){
        ResultResp resultResp = new ResultResp();
        resultResp.setMessage(message);
        resultResp.setCode(code);
        return resultResp;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# @RestControllerAdvice

  • 作用:是 @ControllerAdvice 和 @ResponseBody 的组合注解,专为 RESTful API 设计。
  • 特点:返回值会自动序列化为 JSON/XML 响应体,无需手动添加 @ResponseBody。
@RestControllerAdvice
public class GlobalExceptionHandler {
    // 异常处理方法
}
1
2
3
4

# @ExceptionHandler

  • 作用:标记异常处理方法,指定处理的异常类型。
  • 特点:
    • 可以定义多个方法处理不同类型的异常。
    • 支持捕获异常的子类。
@ExceptionHandler(ServiceException.class)
public ResponseEntity<?> handleServiceException(ServiceException e) {
    return ResponseEntity.status(HttpStatus.BAD_REQUEST)
                           .body(e.getMessage());
}
1
2
3
4
5

# ErrorrController接口

异常系统统一映射到 /error , 你可以实现 ErrorController来实现异常的控制

@Controller
@RequestMapping(value = "/error")
public class CustomizeErrorController implements ErrorController {

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request
                .getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        try {
            return HttpStatus.valueOf(statusCode);
        } catch (Exception ex) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
    }

    @RequestMapping(produces = MediaType.TEXT_HTML_VALUE)
    public ModelAndView errorHtml(HttpServletRequest request, Model model) {
        HttpStatus status = getStatus(request);
        if (status.is4xxClientError()) {
            model.addAttribute("message", "你这个请求错了吧,要不然换个姿势?");
        }
        if (status.is5xxServerError()) {
            model.addAttribute("message", "服务冒烟了,要不然你稍后再试试!!!");
        }

        return new ModelAndView("error");
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 扩展

当然@ControllerAdvice还可实现,全局数据绑定以及全局数据预处理,这里就不展开了。

ControllerAdvice扩展-博客 (opens new window)

# 全局异常处理

在编写异常处理代码时,我们通常选择定义一个全局类,这样以便实现:集中处理所有异常,避免在每个 Controller 中重复编写 try-catch。

@RestControllerAdvice
public class GlobalExceptionHandler {

    // 处理自定义异常
    @ExceptionHandler(ServiceException.class)
    public Result<?> handleServiceException(ServiceException e) {
        return Result.error(e.getStatus().getCode(), e.getMessage());
    }

    // 处理运行时异常
    @ExceptionHandler(RuntimeException.class)
    public Result<?> handleRuntimeException(RuntimeException e) {
        return Result.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    // 处理其他异常
    @ExceptionHandler(Exception.class)
    public Result<?> handleException(Exception e) {
        return Result.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统内部错误");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 注意事项

# 1.避免重复 try-catch

  • 全局异常处理器可以替代大部分 try-catch,减少冗余代码。
  • 仅在需要特殊处理的场景(如事务回滚)中使用局部 try-catch。

# 2. 异常类的继承关系

  • 自定义异常应继承 RuntimeException(运行时异常),而非 Exception(检查型异常)。
  • 检查型异常(如 IOException)需显式处理,而运行时异常可自动抛出。

# 3. 安全性

  • 避免暴露敏感信息:返回给前端的异常信息应简洁,不包含堆栈跟踪或数据库密码等敏感数据。
  • 日志记录:在异常处理方法中记录详细日志,便于排查问题。

# 4.优先级与覆盖

  • 如果多个 @ControllerAdvice 类处理同一异常,优先使用 最近声明的类。
  • 可通过 @Order 注解显式指定优先级。
上次更新: 2025/05/21, 15:29:11
SpringBoot中关于日志的更好使用
时间跟其他数据的序列化

← SpringBoot中关于日志的更好使用 时间跟其他数据的序列化→

最近更新
01
面向切面跟自定义注解的结合
05-22
02
时间跟其他数据的序列化
05-19
03
数据加密与安全
05-17
更多文章>
Theme by Vdoing | Copyright © 2023-2025 EffectTang
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式