• JSR303校验注解 and 统一异常处理


    目录

    JSR303校验注解概念

    作用:

    应用:

    应用

    第一步:添加依赖

    第二步:在实体类上添加相应的注解@NotBlank......

    第三步:@Valid开启校验功能,并且会有默认的响应

    第四步: 给校验的bean后紧跟一个BindResult,就可以获得校验的结果

    第五步: 统一异常处理

    1、首先定义一个枚举类,用于定义错误码和错误信息

    2、然后定义一个异常处理类

    3、结果示例


    JSR303校验注解概念

    作用:

                    用来校验后端实体类的属性是否合法

    应用:

                    直接给Bean类的 属性加上校验注解即可

    应用

    第一步:添加依赖

    <!--校验数据的JSR303依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
        <version>2.7.0</version>
    </dependency>
            <dependency>
                <groupId>javax.validation</groupId>
                <artifactId>validation-api</artifactId>
                <version>2.0.1.Final</version>
            </dependency>

    第二步:在实体类上添加相应的注解@NotBlank......

    校验            @URL 
    自定义校验      @Pattern(regexp = 正则表达式",message = "提示信息")
    
    /**
     * 品牌名
     */
    @NotBlank(message = "品牌名不许为空,且必须提交")
    private String name;

    第三步:@Valid开启校验功能,并且会有默认的响应

    public R save(@Valid @RequestBody BrandEntity brand){
    brandService.save(brand);
          return R.ok();
      }

    第四步: 给校验的bean后紧跟一个BindResult,就可以获得校验的结果

    1. public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){
    2. if (result.hasErrors()){
    3. Map<String,String> map = new HashMap<>();
    4. // 1、 获取校验的错误信息
    5. result.getFieldErrors().forEach((item)->{
    6. // 2、 获得校验的错误信息
    7. String message = item.getDefaultMessage();
    8. // 3、获得错误的属性的名字
    9. String field = item.getField();
    10. map.put(field,message);
    11. });
    12. return R.error(400,"提交的数据不合法 ").put("data",map);
    13. }else {
    14. brandService.save(brand);
    15. }
    16. return R.ok();
    17. }

    缺点:需要每个类都要加,代码过于复杂化。

    解决办法:统一异常处理

    第五步: 统一异常处理

            在spring框架下实现一个异常处理的类,用 @RestControllerAdvice + @ExceptionHandler

    1、首先定义一个枚举类,用于定义错误码和错误信息

    1. /***
    2. * 错误码和错误信息定义类
    3. * 1. 错误码定义规则为5为数字
    4. * 2. 前两位表示业务场景,最后三位表示错误码。例如:100001。10:通用 001:系统未知异常
    5. * 3. 维护错误码后需要维护错误描述,将他们定义为枚举形式
    6. * 错误码列表:
    7. * 10: 通用
    8. * 001:参数格式校验
    9. * 11: 商品
    10. * 12: 订单
    11. * 13: 购物车
    12. * 14: 物流
    13. *
    14. *
    15. */
    16. public enum BizCodeEnume {
    17. UNKNOW_EXCEPTION(10000,"系统未知异常"),
    18. VAILD_EXCEPTION(10001,"参数格式校验失败");
    19. private int code;
    20. private String msg;
    21. BizCodeEnume(int code,String msg){
    22. this.code = code;
    23. this.msg = msg;
    24. }
    25. public int getCode() {
    26. return code;
    27. }
    28. public String getMsg() {
    29. return msg;
    30. }
    31. }

    2、然后定义一个异常处理类

            用 @RestControllerAdvice + @ExceptionHandler进行修饰,即@RestControllerAdvice默认会拦截 controller类上抛出的不能处理的异常

            一个全局异常处理类需要处理三类异常: 1.业务类异常 (引入:https://www.jb51.net/article/215324.htm),2.运行时异常 ,3.Error

    1. /**
    2. * 异常处理类:集中处理所有异常
    3. **/
    4. @Slf4j// 日志记录
    5. /*
    6. @ResponseBody
    7. @ControllerAdvice(basePackages = "com.atguigu.gulimail.product.controller")
    8. */
    9. @RestControllerAdvice
    10. public class GuLiMailException {
    11. /**
    12. * 特定异常(运行时异常)
    13. * @param e
    14. * @return
    15. */
    16. @ExceptionHandler(value = Exception.class)// 表示感知所有异常
    17. public R handleValidException (MethodArgumentNotValidException e /*MethodArgumentNotValidException可以更换异常类型*/){
    18. // 控制台错误日志记录输出
    19. log.error("数据校验出现问题{},异常理性{}",e.getMessage(),e.getClass());
    20. // 封装错误信息集合
    21. Map<String,String> map = new HashMap<>();
    22. // 获取绑定的校验的结果
    23. BindingResult bindingResult = e.getBindingResult();
    24. // 1获得所有的校验错误信息进行遍历
    25. bindingResult.getFieldErrors().forEach((item)->{
    26. // 2、 获得校验的错误信息
    27. String message = item.getDefaultMessage();
    28. // 3、获得错误的属性的名字
    29. String field = item.getField();
    30. map.put(field,message);
    31. });
    32. return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(), BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",map);
    33. }
    34. /**
    35. * 全局异常处理; 不论出现那种异常,都会执行
    36. 上面的只是异常中的一个类,不能包含所有的异常体系,还有一大类是叫Error(系统级异常),所以需要有一个兜底的异常捕获:
    37. */
    38. @ExceptionHandler(value = Throwable.class)
    39. public R handleException(Throwable throwable){
    40. return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg());
    41. }
    42. }

    3、结果示例

  • 相关阅读:
    【聊天系统的优化】RPC方式的优化
    【Redis面试题(46道)】
    接口测试的几种方法
    ES6 class 类
    前端 JS 经典:浏览器中 ESModule 的工作原理
    springboot下的mybatis打印sql语句
    如何在three.js中画3D圆弧及半圆弧组成圆
    Python in Visual Studio Code 2023年9月更新
    MySQL权限控制、分区表、快速复制表
    子进程变成僵尸进程
  • 原文地址:https://blog.csdn.net/qq_45763504/article/details/125616616