全局异常处理
在Controller 处理请求过程中发生了异常,DispatcherServlet 将异常处理委托给异常处理器(处理异常的类)实现HandlerExceptionResolver 接口的都是异常处理类。
项目的异常一般集中处理,定义全局异常处理器。在结合框架提供的注解,诸如:@ExceptionHandler,@ControllerAdvice,@RestControllerAdvice 一起完成异常的处理。@ControllerAdvice与@RestControllerAdvice 区别在于: @RestControllerAdvice 加了@RepsonseBody。
创建项目 Lession16-ExceptionHandler,Maven 构建工具,JDK19。依赖选择 Spring Web,Lombok,Thymeleafi包名称 com.bipowernode.eh。
1: 全局异常处理器
方式一
@ControllerAdvice
public class GlobalException {
@ExceptionHandler({ArithmeticException.class})
public String handlerArithmeticException(ArithmeticException e, Model model){
String error = e.getMessage();
model.addAttribute("error", error);
return "exp";
}
}
方式二
@ControllerAdvice
public class GlobalException {
@ExceptionHandler({ArithmeticException.class})
@ResponseBody public Map<String, Object> handlerDefaultException(ArithmeticException e){
Map<String, Object> err = new HashMap<>();
err.put("msg", e.getMessage());
err.put("tips", "被除数不能为零");
return err;
}
}
@RestController
public class NumberController {
@PostMapping("/divide")
public String divide(Integer n1, Integer n2){
return "n1/n2=" + n1 / n2;
}
}
2: BeanVaildator
@Data
public class OrderV0 {
@NotBlank(message = "订单名称不能为空")
private String name;
@NotNull(message = "商品必须有数量")
@Range(min = 1, max = 99, message = "一个订单的商品数量在{min}-{max}")
private Integer amount;
@NotNull(message = "用户不能为空")
@Min(value = 1, message = "从1开始")
private Integer userId;
}
@ControllerAdvice
public class GlobalException {
@ExceptionHandler({BindException.class})
public Map<String, Object> handlerJRS303Exception(BindException e){
Map<String, Object> err = new HashMap<>();
System.out.println("====JSR303====");
BindingResult result = e.getBindingResult();
if (result.hasErrors()) {
List<FieldError> fieldErrors = result.getFieldErrors();
for(int i = 0, len = fieldErrors.size(); i < len; i ++){
FieldError fieldError = fieldErrors.get(i);
err.put(i + "-" + fieldError.getField(), fieldError.getDefaultMessage());
}
}
return err;
}
}
@RestController
public class OrderController {
@PostMapping("/order/add")
public String createOrder(@Validated @RequestBody OrderV0 order){
return order.toString();
}
}