Lingmoumou's Blog

きっといつかって愿うまま

0%

SpringBoot 自定义异常类

有的时候,我们需要业务逻辑时抛出自定义异常,这个时候需要自定义业务异常类。

  • Exception:受检查的异常,这种异常是强制我们catch或throw的异常。你遇到这种异常必须进行catch或throw,如果不处理,编译器会报错。比如:IOException。
  • RuntimeException:运行时异常,这种异常我们不需要处理,完全由虚拟机接管。比如我们常见的NullPointerException,我们在写程序时不会进行catch或throw。
    RuntimeException也是继承自Exception的,只是虚拟机对这两种异常进行了区分。

常见异常类型

常见的RuntimeException类型的异常

  • ArithmeticException:数学计算异常。
  • NullPointerException:空指针异常。
  • NegativeArraySizeException:负数组长度异常。
  • ArrayOutOfBoundsException:数组索引越界异常。
  • ClassNotFoundException:类文件未找到异常。
  • ClassCastException:类型强制转换异常。
  • SecurityException:违背安全原则异常。

其他非RuntimeException类型的常见异常

  • NoSuchMethodException:方法未找到异常。
  • IOException:输入输出异常。
  • EOFException:文件已结束异常。
  • FileNotFoundException:文件未找到异常。
  • NumberFormatException:字符串转换为数字异常。
  • SQLException:操作数据库异常

SpringBoot默认的错误处理机制

在浏览器中访问错误请求时,会返回一个状态码以及一个错误页面;当用App访问错误请求时,在Body中返回的是一个json,json中的status为状态码。
SpringBoot中是通过如下源代码来实现不同的请求有不同的相应。
BasicErrorController.java

自定义异常

  1. 需要编写一个exception类继承RuntimeException类;
  2. 编写一个handler类处理controller层抛出的异常;
  3. 在controller的请求方法中抛出这个异常。
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
// UserNotExistException.java

@Data
@EqualsAndHashCode(callSuper=false)
public class UserNotExistException extends RuntimeException{

private static final long serialVersionUID = -3762363757873984368L;

private String id;

public UserNotExistException(String id){
super("user not exist");
this.id=id;
}

}

// ControllerExceptionHandler.java

@ControllerAdvice
public class ControllerExceptionHandler {

@ExceptionHandler(UserNotExistException.class)
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String,Object> handlerUserNotExistException(UserNotExistException ex){

Map<String,Object> result=new HashMap<>();
result.put("id",ex.getId());
result.put("message",ex.getMessage());
return result;
}
}

// UserController.java

@Slf4j
@RestController
public class UserController {

@GetMapping("/user/{id:\\d+}")
public User getErrorInfo(@PathVariable String id){
// throw new RuntimeException("user not exist");
throw new UserNotExistException(id);
}
}

Spring相关常用注解

@ControllerAdvice

这是一个增强的 Controller。可以实现三个方面的功能:

  • 全局异常处理:结合@ExceptionHandler
  • 全局数据绑定:结合@ModelAttribute。全局数据绑定功能可以用来做一些初始化的数据操作,我们可以将一些公共的数据定义在添加了 @ControllerAdvice 注解的类中,这样,在每一个 Controller 的接口中,就都能够访问导致这些数据。
  • 全局数据预处理:结合@InitBinder

如果全部异常处理都返回json,那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice ,这样在方法上就可以不需要添加 @ResponseBody。@RestControllerAdvice在注解上已经添加了@ResponseBody。

@ExceptionHandler

用来指明异常的处理类型

需要注意的是使用@ExceptionHandler注解传入的参数可以一个数组,且使用该注解时,传入的参数不能相同,也就是不能使用两个@ExceptionHandler去处理同一个异常。如果传入参数相同,则初始化ExceptionHandler时会失败。

参考文献