JSR303校验
JSR303校验
在实体类上面加注解@NotBlank
等等:
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 品牌id
*/
@TableId
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名不能为空")
private String name;
/**
* 品牌logo地址
*/
@NotEmpty
@URL(message = "logo必须是一个合法的url地址")
private String logo;
/**
* 介绍
*/
private String descript;
/**
* 显示状态[0-不显示;1-显示]
*/
private Integer showStatus;
/**
* 检索首字母
*/
@NotEmpty
@Pattern(regexp = "/^[a-zA-Z]$/",message = "检索首字母必须是一个字母")
private String firstLetter;
/**
* 排序
*/
@NotNull
@Min(value = 0,message = "排序必须大于等于0")
private Integer sort;
}
控制器中加注解@Valid
:
/**
* 保存
*/
@RequestMapping("/save")
//@RequiresPermissions("product:brand:save")
public R save(@Valid @RequestBody BrandEntity brand, BindingResult result) {
if (result.hasErrors()) {
Map<String, String> map = new HashMap<>();
result.getFieldErrors().forEach((item) -> {
//获取到错误提示
String message = item.getDefaultMessage();
//获取错误的属性的名字
String field = item.getField();
map.put(field, message);
});
return R.error(400, "submit data not valid").put("data", map);
}
brandService.save(brand);
return R.ok();
}
BindingResult要紧跟在校验的后面
测试结果:
统一异常校验:
@RestControllerAdvice(basePackages = "com.cxk.gulimall.product.controller")
@Slf4j
public class GulimallExceptionControllerAdvice {
@ExceptionHandler(value = {MethodArgumentNotValidException.class})
public R handleVaildException(MethodArgumentNotValidException e) {
log.error("数据校验出现异常,异常类型:{}", MethodArgumentNotValidException.class);
BindingResult bindingResult = e.getBindingResult();
Map<String, String> map = new HashMap<>();
bindingResult.getFieldErrors().forEach((item) -> {
map.put(item.getField(), item.getDefaultMessage());
});
return R.error(BizCodeEnum.VALID_EXCEPTION.getCode(), BizCodeEnum.VALID_EXCEPTION.getMsg())
.put("data", map);
}
@ExceptionHandler(value = Exception.class)
public R handleException(Exception e) {
return R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(), BizCodeEnum.UNKNOW_EXCEPTION.getMsg());
}
}
状态码枚举:
public enum BizCodeEnum {
UNKNOW_EXCEPTION(10000, "系统未知异常"),
VALID_EXCEPTION(10001, "参数格式校验失败");
private Integer code;
private String msg;
BizCodeEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
JSR303分组校验
创建两个类,增加和修改分组:
public interface AddGroup {
}
public interface UpdateGroup {
}
给实体类增加组:
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 品牌id
*/
@TableId
@NotNull(message = "品牌id必须提交",groups = {UpdateGroup.class})
@Null(message = "新增不能指定id",groups = {AddGroup.class})
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名不能为空",groups = {UpdateGroup.class,AddGroup.class})
private String name;
/**
* 品牌logo地址
*/
@NotBlank(message = "logo不能为空",groups = {AddGroup.class})
@URL(message = "logo必须是一个合法的url地址",groups = {UpdateGroup.class,AddGroup.class})
private String logo;
/**
* 介绍
*/
private String descript;
/**
* 显示状态[0-不显示;1-显示]
*/
private Integer showStatus;
/**
* 检索首字母
*/
@NotEmpty(groups = {AddGroup.class})
@Pattern(regexp = "/^[a-zA-Z]$/",message = "检索首字母必须是一个字母",groups = {UpdateGroup.class,AddGroup.class})
private String firstLetter;
/**
* 排序
*/
@NotNull(message = "排序不能为空",groups = {AddGroup.class})
@Min(value = 0,message = "排序必须大于等于0",groups = {UpdateGroup.class,AddGroup.class})
private Integer sort;
}
控制器上面添加组:
/**
* 保存
*/
@RequestMapping("/save")
//@RequiresPermissions("product:brand:save")
public R save(@Validated(AddGroup.class) @RequestBody BrandEntity brand) {
brandService.save(brand);
return R.ok();
}
/**
* 修改
*/
@RequestMapping("/update")
//@RequiresPermissions("product:brand:update")
public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand) {
brandService.updateById(brand);
return R.ok();
}
自定义校验规则
创建一个ListValue注解:
@Documented
@Constraint(validatedBy = {ListValueConstraintValidator.class})
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.cxk.common.validator.ListValue.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
int[] vals() default {};
}
在Resources目录下面创建ValidationMessages.properties
com.cxk.common.validator.ListValue.message = 必须提交给定的值
创建一个ListValueConstraintValidator类,只允许制定的整数
public class ListValueConstraintValidator implements ConstraintValidator<ListValue, Integer> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(ListValue constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int val : vals) {
set.add(val);
}
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
在实体类上面加注解:
/**
* 显示状态[0-不显示;1-显示]
*/
@NotNull(groups = {AddGroup.class, UpdateStatusGroup.class})
@ListValue(vals = {0,1},groups = {AddGroup.class, UpdateStatusGroup.class})
private Integer showStatus;