文章目录

  • 常用校验注解
  • BeanValidation中内置的
  • Hibernate Validator 附加的 constraint
  • 分组校验
  • 分组校验的作用
  • 分组校验的步骤
  • 自定义校验注解
  • 自定义校验注解的作用
  • 自定义校验注解的编写步骤
  • SpringBoot中配置统一异常处理类
  • 作用:统一对项目中的异常进行处理
  • 使用步骤


常用校验注解

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 被注释的元素必须在合适的范围内

分组校验

分组校验的作用

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

分组校验的步骤

  • 编写自定义的分组接口,接口的接口名代表分组的组名
  • 注意:使用了分组校验的字段,只会在形参上的@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());
    }
}