1.1 JSR分组校验
1.1.1 给Bean添加校验注解:javax.validation.constrints
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 品牌id
@notnull不能为 null,但可以为 empty,一般用在 Integer 类型的基本数据类型的非空校验上,而且被其标注的字段 可以使用 @size、@Max、@Min 对字段数值进行大小的控制
@notEmpty不能为 null,且长度必须大于 0,一般用在集合类上或者数组上
@notBlank只能作用在接收的 String 类型上,注意是只能,不能为 null,而且调用 trim() 后,长度必须大于 0即: 必须有实际字符
*/
@TableId(type= AUTO)
@NotNull(message = "修改品牌id不能为空", groups = {UpdateGroup.class})
@Null(message = "新增不能指定id", groups = {AddGroup.class})
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名不能为空")
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-显示]
*/
@NotNull(message = "显示状态不能为空",groups = {AddGroup.class,UpdateGroup.class})
@ListValue(vals={0,1},message="显示状态只能是[0-不显示;1-显示]",groups = {AddGroup.class, UpdateStatus.class})
private Integer showStatus;
/**
* 检索首字母
*/
@NotEmpty(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;
}
1.1.2 开启校验功能@Valid,效果:校验错误以后会有默认的响应
@RequestMapping("/update/status")
//@Validdated 注解可以分组
public R updateStatus(@Validated(value = UpdateStatus.class)@RequestBody BrandEntity brand) {
brandService.updateById(brand);
return R.ok();
}
1.1.3 给校验的bean后紧跟一个BindResult,就可以获取到检验结果
@ExceptionHandler(value =MethodArgumentNotValidException.class)
//数据校验异常 也可以返回ModelAndView
public R handleValidException(MethodArgumentNotValidException exception) {
Map<String, String> map = new HashMap<>();
// 获取数据校验的错误结果
BindingResult bindingResult = exception.getBindingResult();
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);*/
return R.error(BizCodeEnum.UN_KNOW_EXCEPTION.getCode(),
BizCodeEnum.UN_KNOW_EXCEPTION.getMsg()).put("data", map);
}
@ExceptionHandler(value = Throwable.class)
public R handleException(Throwable throwable) {
log.error("未知异常{},异常类型{}", throwable.getMessage(), throwable.getClass());
return R.error(400, "数据校验出现问题");
}
1.1.4 分组校验(多环境的复杂校验)
- @NotBlank(message=“品牌名必须提交”,group={AddGroup}) 给校验注解标示什么情况要进行校验
- @Validated({AddGroup.class})
1.1.5自定义校验
-
编写一个自定义的校验注解
@Documented @Constraint( validatedBy = {ListValueConstraintValidator.class} )//指定校验器 可以指定多个 @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE}) @Retention(RetentionPolicy.RUNTIME) public @interface ListValue { String message() default "{com.example.common.valid.ListValue.message}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; int[] vals() default { }; }
-
编写一个自定义的校验器 ConStrainValidator
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> { private Set<Integer> set=new HashSet<>(); @Override public void initialize(ListValue constraintAnnotation) { //获得注解的所有value int[] vals=constraintAnnotation.vals(); for(int val:vals){ set.add(val); } } @Override public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) { //如果传过来的数据 注解里面没有则校验不合格 return set.contains(integer); } }
-
关联自定义的校验器和自定义的校验注解@Constraint(validatedBy = {ListValueConstraintValidator.class})