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
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
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
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
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
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
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