JSR303(java规范)数据校验规范

常用校验注解

BeanValidation中内置的

  • @Null 被注释的元素必须为 null
  • @NotNull 被注释的元素必须不为 null
  • @AssertTrue 被注释的元素必须为 true
  • @AssertFalse 被注释的元素必须为 false
  • @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  • @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  • @Size(max, min) 被注释的元素的大小必须在指定的范围内
  • @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
  • @Past 被注释的元素必须是一个过去的日期
  • @Future 被注释的元素必须是一个将来的日期
  • @Pattern(value) 被注释的元素必须符合指定的正则表达式

Hibernate Validator 附加的 constraint

  • @Email 被注释的元素必须是电子邮箱地址
  • @Length 被注释的字符串的大小必须在指定的范围内
  • @NotEmpty 被注释的字符串的必须非空
  • @Range 被注释的元素必须在合适的范围内

分组校验

分组校验的作用

  • 在项目中,增删查改的四种表单的提交方式中,对表单字段的校验要求不一样,使用分组校验,可以完成,同一个字段在不同方式下,不同的校验规则。

分组校验的步骤

  • 编写自定义的分组接口,接口的接口名代表分组的组名

    • image-20211207175150430
  • 注意:使用了分组校验的字段,只会在形参上的@Validate注解表明了分组,才会进行校验。举例:假如你有个字段只表明了分组校验的注解,那么在@Validate没有表明分组的情况下,是不会校验的。

  • 在实体类中,用注解标注需要使用分组校验的字段以及规则

    • @Data
      @TableName("pms_brand")
      public class BrandEntity implements Serializable {
      	private static final long serialVersionUID = 1L;
      
      	/**
      	 * 品牌id
      	 */
      	@NotNull(message = "修改时ID不能为空",groups = {UpdateGroup.class,UpdateStatusGroup.class})
      	@Null(message = "增加时ID必须为空",groups = {AddGroup.class})
      	@TableId
      	private Long brandId;
      	/**
      	 * 品牌名
      	 */
      	@NotBlank(message = "增加时商品名称不能为空",groups = {AddGroup.class})
      	private String name;
      	/**
      	 * 品牌logo地址
      	 */
      	@NotBlank(message = "增加时logo不能为空",groups = {AddGroup.class})
      	@URL(message = "logo必须为一个规范的URL地址",groups = {AddGroup.class, UpdateGroup.class})
      	private String logo;
      	/**
      	 * 介绍
      	 */
      	private String descript;
      	/**
      	 * 显示状态[0-不显示;1-显示]
      	 */
      	@ListValue(val = {0,1},groups = {UpdateStatusGroup.class,AddGroup.class,UpdateGroup.class})
      	@NotNull(message = "增加与修改状态时不能为空",groups = {AddGroup.class, UpdateStatusGroup.class})
      	private Integer showStatus;
      	/**
      	 * 检索首字母
      	 */
      	@NotBlank(message = "增加时检索字母不能为空",groups = {AddGroup.class})
          @Pattern(regexp = "^[a-zA-Z]$",message ="检索字母必须是a-z或A-Z",groups = {AddGroup.class, UpdateGroup.class})
      	private String firstLetter;
      	/**
      	 * 排序
      	 */
      	@NotNull(message = "增加时排序字段不能为空",groups = {AddGroup.class})
      	@Min(value = 0,message = "排序字段必须大于0",groups = {AddGroup.class, UpdateGroup.class})
      	private Integer sort;
      
      }
      
  • 在Controller中需要校验的形参上标注@validated注解

    • public R update(@Validated(value = {UpdateGroup.class}) @RequestBody BrandEntity brand) {
              //brandService.updateById(brand);
              //brand的表若是更新了name属性,相应的CategoryBrandRelation表的name冗余字段的值也要变
              brandService.updateByIdCascader(brand);
              return R.ok();
          }
      

自定义校验注解

自定义校验注解的作用

  • 当JSR303内置的注解,满足不了项目的校验要求,可以通过自定义校验注解完成参数的校验

自定义校验注解的编写步骤

  • 添加依赖

    <!--校验-->
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>2.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.4.1.Final</version>
    </dependency>
    <!--高版本需要javax.el-->
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.el</artifactId>
        <version>3.0.1-b08</version>
    </dependency>
    
  • 编写自定义注解类

    @Documented
    //表明该自定义注解使用的校验器是什么,这里写上了自己声明的自定义校验器
    @Constraint(validatedBy = {ListValueDoubleValidator.class, ListValueIntegerValidator.class})
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    
    public @interface ListValue {
        
    	//错误信息,必须具有的属性
        //该属性去ValidationMessages.properties中取值
        //这里也可以直接写上错误信息
        String message() default "{com.guolei.common.valid.myvalidAnno.validAnno.ListValue}";
    	//分组校验,必须具有的属性
        Class<?>[] groups() default { };
    	//自定义负载信息,必须具有的属性
        Class<? extends Payload>[] payload() default { };
    
        //数组,用户自己指定
        int[] val() default {};
    
    }
    
  • 在对应项目的resources包下,建立ValidationMessages.properties,配置错误信息取值(这一步不是必须)

    com.guolei.common.valid.myvalidAnno.validAnno.ListValue=必须提交指定的值
    
  • 编写自定义注解类所使用的自定义校验器

    public class ListValueDoubleValidator implements ConstraintValidator<ListValue,Double> { //<自定义注解类名,校验值类型>
        private Set<Double> set=new HashSet<>();
        @Override
        //初始化,获得自定义注解的内容
        public void initialize(ListValue constraintAnnotation) {
            int[] val = constraintAnnotation.val();
            //在例子中这个val取出来的值是,0,1
            if(val!=null){
                for (double i : val) {
                    set.add(i);
                }
            }
        }
    	
        //覆盖验证逻辑
        @Override
        public boolean isValid(Double dou, ConstraintValidatorContext constraintValidatorContext) {
            //这里写验证逻辑,通过返回true,不通过返回false
            //在例子中,当传来表单的字段showStatus的值不为0,1时,校验失败
            return set.contains(dou);
        }
    }
    
    
  • 使用实例

    /**
    	 * 显示状态[0-不显示;1-显示]
    	 */
    	@ListValue(val = {0,1},groups = {UpdateStatusGroup.class,AddGroup.class,UpdateGroup.class})
    	@NotNull(message = "增加与修改状态时不能为空",groups = {AddGroup.class, UpdateStatusGroup.class})
    	private Integer showStatus;
    

SpringBoot中配置统一异常处理类

作用:统一对项目中的异常进行处理

使用步骤

  • 创建一个统一异常处理类

    /**
    *@autho GuoLei
    *@Description 
    * produc微服务controller异常统一处理类
    */
    @Slf4j
    //该注解表明该异常处理类,统一处理那个包下的异常
    //Rest表明该异常处理类的方法返回值以JSON数据的格式返回
    @RestControllerAdvice(basePackages = "com.guolei.gulimall.product.controller")
    public class ContorllerExceptionHandler {
    	
        //该注解表明方法处理什么类型的异常
        //这里统一处理了数据的校验异常
        @ExceptionHandler(value = MethodArgumentNotValidException.class)
        public R handleValidException(MethodArgumentNotValidException e) {
            BindingResult result = e.getBindingResult();
            log.error("数据校验异常");
            Map<String, String> resmap = new HashMap<>();
            result.getFieldErrors().forEach((item) -> {
                resmap.put(item.getField(), item.getDefaultMessage());
            });
            return R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(), BizCodeEnum.VAILD_EXCEPTION.getMessage())
                    .put("data",resmap);
        }
    
        //最大的异常处理方法
        @ExceptionHandler(value = Throwable.class)
        public R handleException(Throwable throwable) {
            return R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(), BizCodeEnum.UNKNOW_EXCEPTION.getMessage());
        }
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值