数据校验(前端数据校验、JSR303校验)

简介: 数据校验(前端数据校验、JSR303校验)

数据校验


前端数据校验


就是规定添加的属性要符合规定,不然会出现想不到的异常!

例如:添加品牌选项框中,设置检索首字母那么我们就要规定首字母不能是多个字母只能是a-z或A-Z之间的一个

那么我们就可以对这个输入框进行绑定,如下

image.png

实现效果如下:

image.png


JSR303数据校验


后端的处理前端传来的数据时,虽然前端已做限制但是还不够严谨,例如我们可以跳过页面通过一些工具直接发送请求也可以完成添加等操作,所以后端也需要做数据校验!

java中也提供了一系列的校验方式,它这些校验方式在“javax.validation.constraints”包中,@Email,@NotNull等注解。

一、添加依赖

后面可能其他模块也能用到,所以这里把依赖添加到common模块


<!--jsr3参数校验器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.3.2.RELEASE</version>
</dependency>

这个依赖提供了NotNull,@NotBlank和@NotEmpty这些判断

二、给需要校验的bean添加注解

/**
 * 品牌
 * 
 * @author xiaocai
 * @email mildcaq@gmail.com
 * @date 2022-07-27 21:05:30
 */
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
   private static final long serialVersionUID = 1L;
   /**
    * 品牌id
    */
   @TableId
   private Long brandId;
   /**
    * 品牌名
    */
   @NotBlank
   private String name;
   /**
    * 品牌logo地址
    */
   private String logo;
   /**
    * 介绍
    */
   private String descript;
   /**
    * 显示状态[0-不显示;1-显示]
    */
   @NotNull
   private Integer showStatus;
   /**
    * 检索首字母
    */
   @NotEmpty
   private String firstLetter;
   /**
    * 排序
    */
   @NotNull
   @Min(0)
   private Integer sort;
}

未在控制类中指定方法开启校验时如下:

image.png

controller中给请求方法加校验注解@Valid,开启校验,

/**
 * 保存
 */
@RequestMapping("/save")
public R save(@RequestBody @Valid BrandEntity brand){
    brandService.save(brand);
    return R.ok();
}

这里我错误信息只返回是Bad Request

视频中老师所讲的是有详细信息的,这个差异应该是版本原因不影响!

image.png

这种返回的错误结果并不符合我们的业务需要。我们想让捕捉这个错误的详细信息,并且能够统一返回我们自定义的信息!

三、通过BindResult捕获校验结果

修改内容如下:

@RequestMapping("/save")
public R save(@Valid @RequestBody BrandEntity brand,BindingResult result){
    if( result.hasErrors()){
        Map<String,String> map=new HashMap<>();
        //1.获取错误的校验结果
        result.getFieldErrors().forEach((item)->{
            //获取发生错误时的message
            String message = item.getDefaultMessage();
            //获取发生错误的字段
            String field = item.getField();
            map.put(field,message);
        });
        return R.error(400,"提交的数据不合法").put("data",map);
    }else {
    }
    brandService.save(brand);
    return R.ok();
}

再次测试

好啦,这下把错误信息都捕获到喽!

image.png

但是,这种是针对于该请求设置了一个内容校验,如果针对于每个请求都单独进行配置,显然不是太合适,实际上可以统一的对于异常进行处理

四、统一异常处理

可以使用SpringMvc所提供的@ControllerAdvice,通过“basePackages”能够说明处理哪些路径下的异常。

(1)抽取一个异常处理类

详细信息都写在了注释里,可以作为参考!!!


@Slf4j
@RestControllerAdvice(basePackages = "com.caq.mall.product.controller")
public class MallExceptionAdvice {
    //指定的包下所有的校验异常都会被这个方法捕捉
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleValidException(MethodArgumentNotValidException exception) {
        //定义map,存放所有错误信息
        Map<String, String> map = new HashMap<>();
        //通过BindResult捕获校验结果
        BindingResult bindingResult = exception.getBindingResult();
        //遍历校验结果中所有字段的错误,字段为key,错误信息为value存放到map中
        bindingResult.getFieldErrors().forEach(fieldError -> {
            String message = fieldError.getDefaultMessage();
            String field = fieldError.getField();
            map.put(field, message);
        });
//        控制台打印错误信息
        log.error("数据校验出现问题{},异常类型{}", exception.getMessage(), exception.getClass());
//        返回错误结果,并显示所有错误的数据
        return R.error(400, "数据校验出现问题").put("data", map);
    }
}

(2)测试: http://localhost:88/api/product/brand/save

接下来我们去掉我们控制类中save方法的校验,看看统一异常处理能否生效

还是可以哦!

image.png

(3)错误状态码

正规开发过程中,错误状态码有着严格的定义规则


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

(4)默认异常处理

上面的统一异常处理只是针对了校验相关的错误,那么如果是其他异常呢?

那就再来个默认的异常处理呗


@ExceptionHandler(value = Throwable.class)
    public R handleException(Throwable throwable){
        log.error("未知异常{},异常类型{}",throwable.getMessage(),throwable.getClass());
        return R.error(BizCodeEnum.UNKNOW_EXEPTION.getCode(),BizCodeEnum.UNKNOW_EXEPTION.getMsg());
    }

\



相关文章
|
7月前
|
JavaScript 前端开发
前端基础 - JQuery自定义校验器
前端基础 - JQuery自定义校验器
32 0
|
4天前
|
移动开发 前端开发 JavaScript
前端vue3——实现二次元人物拼图校验
前端vue3——实现二次元人物拼图校验
12 1
|
8月前
|
前端开发 Java 数据库
Spring Entity数据校验,分组校验,返回校验结果给前端
Spring Entity数据校验,分组校验,返回校验结果给前端
66 0
|
6月前
|
前端开发 JavaScript
JS前端实现身份证号码合法性校验(校验码校验)
JS前端实现身份证号码合法性校验(校验码校验)
134 0
|
7月前
|
JavaScript 前端开发
前端基础 - JQuery 简单的表单校验器
前端基础 - JQuery 简单的表单校验器
32 0
|
9月前
|
移动开发 前端开发 JavaScript
Vue 利用Canvas标签实现动态验证码校验(前端必备附源码)
Vue 利用Canvas标签实现动态验证码校验(前端必备附源码)
229 0
|
9月前
|
前端开发
前端学习笔记202305学习笔记第二十二天-登录页校验封装和token封装2
前端学习笔记202305学习笔记第二十二天-登录页校验封装和token封装2
42 0
|
9月前
|
前端开发
前端学习笔记202305学习笔记第二十二天-登录页校验封装和token封装1
前端学习笔记202305学习笔记第二十二天-登录页校验封装和token封装1
43 0
|
9月前
|
JSON 算法 前端开发
关于前端动态调试解密签名校验的分享
现在很多项目都进行了签名校验或者是使用例如RSA的方式对传输流量进行加密,那么我们可以通过本地的动态调试获取程序的加密逻辑、加密方法,从而绕过系统的防护对系统进行测试
|
12月前
|
前端开发
前端学习笔记202304学习笔记第七天-必填项校验
前端学习笔记202304学习笔记第七天-必填项校验
39 0