周振林 周振林
首页
  • 前端文章

    • HTML
    • CSS
    • Tailwind CSS (opens new window)
    • JavaScript
    • Vue3
    • 其他
  • Spring
  • SpringMVC
  • Mybatis
  • 安装教程
  • 其他教程
  • 基础
  • 虚拟化
  • Docker
  • OpenStack
  • 心情杂货
关于
收藏

周振林

IT界的小学生
首页
  • 前端文章

    • HTML
    • CSS
    • Tailwind CSS (opens new window)
    • JavaScript
    • Vue3
    • 其他
  • Spring
  • SpringMVC
  • Mybatis
  • 安装教程
  • 其他教程
  • 基础
  • 虚拟化
  • Docker
  • OpenStack
  • 心情杂货
关于
收藏
  • Spring

  • SpringMVC

    • SpringMVC路径映射
    • SpringMVC请求处理
    • SpringMVC响应请求
    • SpringMVC拦截器
    • SpringMVC过滤器
    • SpringMVC异常
      • Spring异常
        • 基础异常处理
        • 响应码异常处理
    • SpringBoot数据校验
  • Mybatis

  • 安装教程

  • 其他教程

  • 后端
  • SpringMVC
周振林
2024-05-22
目录

SpringMVC异常

# Spring异常

在Spring中使用 @ControllerAdvice和@ExceptionHandler处理全局异常。

# 基础异常处理

pom 文件

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
		<optional>true</optional>
</dependency>
1
2
3
4
5
6
7
8
9
10

全局异常处理 GlobalExceptionHandler

// 全局异常处理器
//@ResponseBody
//@ControllerAdvice //告诉SpringMVC,这个组件是专门负责进行全局异常处理的
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 如果出现了异常:本类和全局都不能处理,
     * SpringBoot底层对SpringMVC有兜底处理机制;自适应处理(浏览器响应页面、移动端会响应json)
     * 最佳实践:我们编写全局异常处理器,处理所有异常
     * <p>
     * 前端关心异常状态,后端正确业务流程。
     * 推荐:后端只编写正确的业务逻辑,如果出现业务问题,后端通过抛异常的方式提前中断业务逻辑。前端感知异常;
     */
    @ExceptionHandler(ArithmeticException.class)
    public Object error(ArithmeticException e) {
        System.out.println("【全局】 - ArithmeticException 处理");
        return R.failed(e.getMessage());
    }

    // 最终的兜底
    @ExceptionHandler(Throwable.class)
    public R error(Throwable e) {
        System.out.println("【全局】 - Exception处理" + e.getClass());
        return R.failed(e.getMessage());
    }

}
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

# 响应码异常处理

  • 创建异常枚举,将系统中的所有异常进行分类
  • 创建业务异常类
  • 创建全局异常

BizExceptionEnume类

public enum BizExceptionEnume {

    // ORDER_xxx:订单模块相关异常
    // PRODUCT_xxx:商品模块相关异常

    SYSTEM_ERROR(1001,"系统内部"),
    USER_NOT_FOUND(3001,"用户找不到");

    @Getter
    private Integer code;
    @Getter
    private String msg;

    BizExceptionEnume(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

BizException类

/**
 * 业务异常统一封装
 */
@Data
public class BizException extends RuntimeException {

    private Integer code;
    private String msg;

    public BizException(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }


    public BizException(BizExceptionEnume bizExceptionEnume) {
        this.code=bizExceptionEnume.getCode();
        this.msg=bizExceptionEnume.getMsg();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

GlobalExceptionHandler

// 全局异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler {


    /**
    *如果出现异常 业务逻辑中只需要抛出异常 例如new BizException(BizExceptionEnume.USER_NOT_FOUND),
    *全局异常中捕获异常并返回给前端
    *
    */
    @ExceptionHandler(BizException.class)
    public R handleBizException(BizException e) {
        Integer code = e.getCode();
        String msg = e.getMsg();
        return R.failed(BizExceptionEnume.SYSTEM_ERROR,msg);
    }

    // 最终的兜底
    @ExceptionHandler(Throwable.class)
    public R error(Throwable e) {
        System.out.println("【全局】 - Exception处理" + e.getClass());
        return R.failed(e.getMessage());
    }

}

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

R类

/**
 * 响应信息主体
 *
 */
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class R<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    @Getter
    @Setter
    @JsonPropertyDescription(value = "调用成功返回0,调用失败返回1")
    private int code;

    @Getter
    @Setter
    @JsonPropertyDescription(value = "返回具体的信息")
    private String msg;

    @Getter
    @Setter
    private T data;

    public static <T> R<T> ok() {
        return restResult(null, 0, null);
    }

    public static <T> R<T> ok(T data) {
        return restResult(data, 0, null);
    }

    public static <T> R<T> ok(T data, String msg) {
        return restResult(data, 0, msg);
    }


    public static <T> R<T> failed() {return restResult(null, 1, null);}

    public static <T> R<T> failed(String msg) {
        return restResult(null, 1, msg);
    }

    public static <T> R<T> failed(T data) {
        return restResult(data, 1, null);
    }

    public static <T> R<T> failed(T data, String msg) {
        return restResult(data, 1, msg);
    }

    public static <T> R<T> failed(Integer code,String msg) {
        return restResult(null, code, msg);
    }

    static <T> R<T> restResult(T data, int code, String msg) {
        R<T> apiResult = new R<>();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }

    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    public boolean isOk() {
        return this.code == 0;
    }

}
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
Last Updated: 2025/12/02, 11:22:00
SpringMVC过滤器
SpringBoot数据校验

← SpringMVC过滤器 SpringBoot数据校验→

最近更新
01
查询优化N+1
12-02
02
项目代码组织方式
12-02
03
Mybatis分页插件
12-02
更多文章>
Copyright © 2019-2025 鲁ICP备19032096号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×