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

目录

JSR303校验注解概念

作用:

应用:

应用

第一步:添加依赖

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

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

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

第五步: 统一异常处理

                1、统一异常的三种实现方式:

                2、@RestControllerAdvice + @ExceptionHandler的实现


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  校验       @URL 
自定义校验      @Pattern(regexp = 正则表达式",message = "提示信息")
非空校验        @NotBlank
......

示例:
@NotBlank(message = "品牌名不许为空,且必须提交")
private String name;

引入: 这么多注解怎么找?

 

 

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

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

拓展:

1、分组校验功能。比如:添加页面和修改页面的校验功能不一样

应用

第一步:创建分组校验的接口(接口中什么也不用写,相当于一个标识位)

 第二步:在实体类中的属性上的注解@NotBlank(message = "品牌名不许为空,且必须提交"),增加一个groups属性,来约定是哪种检验规则(增加,或修改)

第三步: 在接口前添加分组校验注解,并指定使用哪种校验规则

2、自定义校验功能。

        第一步:编写一个自定义的校验注解

        第二步:编写一个自定义的校验器

        第三步:关联自定义的校验器和 校验注解

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

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

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

解决办法:统一异常处理

第五步: 统一异常处理

 1、统一异常的三种实现方式:

  介绍:Spring MVC异常统一处理的三种方式 - Louis军 - 博客园        

2、@RestControllerAdvice + @ExceptionHandler的实现

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

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


/***
 * 错误码和错误信息定义类
 * 1. 错误码定义规则为5为数字
 * 2. 前两位表示业务场景,最后三位表示错误码。例如:100001。10:通用 001:系统未知异常
 * 3. 维护错误码后需要维护错误描述,将他们定义为枚举形式
 * 错误码列表:
 *  10: 通用
 *      001:参数格式校验
 *  11: 商品
 *  12: 订单
 *  13: 购物车
 *  14: 物流
 *
 *
 */
public enum BizCodeEnume {
    UNKNOW_EXCEPTION(10000,"系统未知异常"),
    VAILD_EXCEPTION(10001,"参数格式校验失败");

    private int code;
    private String msg;

    BizCodeEnume(int code,String msg){
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

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

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

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

/**
 * 异常处理类:集中处理所有异常
 **/
@Slf4j// 日志记录

/*
@ResponseBody
@ControllerAdvice(basePackages = "com.atguigu.gulimail.product.controller")
*/

@RestControllerAdvice
public class GuLiMailException {

    /**
     * 特定异常(运行时异常)
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)// 表示感知所有异常
    public R handleValidException (MethodArgumentNotValidException e /*MethodArgumentNotValidException可以更换异常类型*/){
        // 控制台错误日志记录输出
        log.error("数据校验出现问题{},异常理性{}",e.getMessage(),e.getClass());
        // 封装错误信息集合
        Map<String,String> map = new HashMap<>();
        // 获取绑定的校验的结果
        BindingResult bindingResult = e.getBindingResult();
        // 1获得所有的校验错误信息进行遍历
        bindingResult.getFieldErrors().forEach((item)->{
                // 2、 获得校验的错误信息
                String message = item.getDefaultMessage();
                // 3、获得错误的属性的名字
                String field = item.getField();
                map.put(field,message);
        });
        return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(), BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",map);
    }

    /**
     * 全局异常处理; 不论出现那种异常,都会执行
上面的只是异常中的一个类,不能包含所有的异常体系,还有一大类是叫Error(系统级异常),所以需要有一个兜底的异常捕获:
     */
    @ExceptionHandler(value = Throwable.class)
    public R handleException(Throwable throwable){
        return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg());
    }

}

3、结果示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值