JSR303字段校验规则(笔记)

时间:2023-02-19 22:57:07

###直接上示例代码

引入依赖(如果项目中没有的话)

<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
entity
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
private static final long serialVersionUID = 1L;

/**
* 品牌id
*/
@NotNull(message = "修改必需指定品牌ID",groups = {UpdateGroup.class})
@Null(message = "新增不能指定品牌ID",groups = {AddGroup.class})
@TableId
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名称不能为空!",groups = {UpdateGroup.class,AddGroup.class})
private String name;
/**
* 品牌logo地址
*/
private String logo;
/**
* 介绍
*/
private String descript;
/**
* 显示状态[0-不显示;1-显示]
*/
@ListValue(vals={0,1},groups = {AddGroup.class})
private Integer showStatus;
/**
* 检索首字母
*/
@Pattern(regexp = "^[a-zA-z]$",message = "检索首字母必须是A-Z的单个字母")
private String firstLetter;
/**
* 排序
*/
private Integer sort;

}
自定义校验注解

@Documented
@Constraint(
validatedBy = {ListValueConstraintValidator.class,ListValueIntegerConstraintValidator.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 "";//这里是取的Resource下面定义的ValidationMessages.properties里面的值

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

String[] vals() default {};
int[] ints() default {};




}
/**
* 自定义校验器(这里定义的是处理类型为Integer的数据,如果有其他数据类型需要校验,可以定义多个校验器,并添加在定义注解的@Constraint中)
*/
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,String/*这里指定校验的类型,如果有多种类型,可以在注解定义的地方指定多个不同的校验类型*/> {
private Set<String> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation) {
//初始化方法 会将ListValue注解中的详细信息给我们
String[] vals = constraintAnnotation.vals();
if(vals ==null)
return;
for(String val : vals){
set.add(val);
}

}

/**
* 判断是否校验成功
* @param value 需要检验的值
* @param constraintValidatorContext
* @return
*/
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
if(StringUtils.isEmpty(value))
return true;
return set.contains(value);
}
}
/**
* 自定义校验器(这里定义的是处理类型为Integer的数据,如果有其他数据类型需要校验,可以定义多个校验器,并添加在定义注解的@Constraint中)
*/
public class ListValueIntegerConstraintValidator implements ConstraintValidator<ListValue,Integer/*这里指定校验的类型,如果有多种类型,可以在注解定义的地方指定多个不同的校验类型*/> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation) {
//初始化方法 会将ListValue注解中的详细信息给我们
int[] vals = constraintAnnotation.ints();
if(vals==null)
return;
for(Integer val : vals){
set.add(val);
}

}

/**
* 判断是否校验成功
* @param value 需要检验的值
* @param constraintValidatorContext
* @return
*/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
if(value==null)
return true;
return set.contains(value);
}
}
定义分组接口

public interface AddGroup {
}
public interface SelectGroup {
}
public interface UpdateGroup {
}
校验规则在接口中的使用

@PostMapping(value = "/generalRecord")
public ResponseData generalRecord( @Validated(AddGroup.class) @RequestBody OdrGeneralQuotaRecordEntity record, BindingResult result) {

if(result.hasErrors()){
List<Map<String,String>> list = new ArrayList<>();
result.getFieldErrors().forEach((item) -> {
//获取到错误提示
Map<String,String> map = new HashMap<>();
String message = item.getDefaultMessage();
String feild = item.getField();
map.put("message",message);
map.put("filed",feild);
list.add(map);
});
return new ResponseData(1001,"提交的数据不合法!",list);
}
return null;
}
在ControllerAdvice中统一处理方式

/**
* 统一异常处理
*/
@Slf4j
@RestControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
public class GulimallExceptionControllerAdvice {

@ExceptionHandler(value = {MethodArgumentNotValidException.class})
public R handleValidException(MethodArgumentNotValidException e){
log.error("数据校验出现问题:{},异常类型:{}",e.getMessage(),e.getClass());
BindingResult result = e.getBindingResult();
if(result.hasErrors()){
List<Map<String,String>> list = new ArrayList<>();
result.getFieldErrors().forEach((item) -> {
//获取到错误提示
Map<String,String> map = new HashMap<>();
String message = item.getDefaultMessage();
String feild = item.getField();
map.put("message",message);
map.put("feild",feild);
list.add(map);
});
return R.error(400,"数据校验出现问题!").put("data",list);
}
return R.error();
}

@ExceptionHandler(value = {Throwable.class})
public R handleException(Throwable throwable){
return R.error(BizCodeEnume.UNKNOWN_EXCEPTION.getCode(),BizCodeEnume.UNKNOWN_EXCEPTION.getMsg()).put("data",throwable.getLocalizedMessage());
}

}