文章目录
- 常用校验注解
- 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());
}
}