83、SpringMVC全局异常处理和数据校验

1、首先定义一个自定义的异常类
@Data
public class BizException extends RuntimeException {

    private Integer code; //业务异常码
    private String msg; //业务异常信息
    public BizException(Integer code, String message) {
        super(message);
        this.code = code;
        this.msg = message;
    }

    public BizException(BizExceptionEnume exceptionEnume) {
        super(exceptionEnume.getMsg());
        this.code = exceptionEnume.getCode();
        this.msg = exceptionEnume.getMsg();
    }
}

2、定义一个异常枚举类

public enum BizExceptionEnume {

    // ORDER_xxx:订单模块相关异常

    // 动态扩充.....
    ID_NOT_NULL(10000,"ID不能为空"),
    PRODUCT_HAS_CLOSED(20001, "商品已下架");
    @Getter
    private Integer code;
    @Getter
    private String msg;
    private BizExceptionEnume(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

3、定义全局异常处理器

@RestControllerAdvice
public class GlobalExceptionHandler {

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


    //处理自定义异常
    @ExceptionHandler(BizException.class)
    public R handleBizException(BizException e) {
        Integer code = e.getCode();
        String msg = e.getMsg();
        return R.error(code, msg);
    }

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R methodArgumentNotValidException(MethodArgumentNotValidException ex) {
        //1、result 中封装了所有错误信息
        BindingResult result = ex.getBindingResult();

        List<FieldError> errors = result.getFieldErrors();
        Map<String, String> map = new HashMap<>();
        for (FieldError error : errors) {
            String field = error.getField();
            String message = error.getDefaultMessage();
            map.put(field, message);
        }
        return R.error(500, "参数错误", map);
    }

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

4、如果出现业务异常代码自己以抛出异常的方式写:throw new BizException(BizExceptionEnume.ID_NOT_NULL);

5、导入参数校验包

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

6、在实体类上的字段上标校验注解

    @NotBlank(message = "员工姓名不能为空")
    private String name;
    @NotNull(message = "员工年龄不能为空")
    private Integer age;
    @Email(message = "邮箱格式不正确")
    private String email;

7、方法上标@Valid注解

    @PostMapping("/employee")
    public R add(@RequestBody @Valid Employee employee){
        employeeService.saveEmp(employee);
        return R.ok();
    }

8、参数校验出错的全局异常处理

   @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R methodArgumentNotValidException(MethodArgumentNotValidException ex) {
        //1、result 中封装了所有错误信息
        BindingResult result = ex.getBindingResult();
        List<FieldError> errors = result.getFieldErrors();
        Map<String, String> map = new HashMap<>();
        for (FieldError error : errors) {
            String field = error.getField();
            String message = error.getDefaultMessage();
            map.put(field, message);
        }
        return R.error(500, "参数错误", map);
    }

 

posted @ 2025-09-10 14:09  shunnWcs  阅读(5)  评论(0)    收藏  举报