JSR303校验 自定义校验 分组校验,

1.依赖

  1. <!--数据校验-->
  2. <dependency>
  3. <groupId>javax.validation</groupId>
  4. <artifactId>validation-api</artifactId>
  5. <version>2.0.1.Final</version>
  6. </dependency>

2.在entity类的属性上添加注解

3.开启校验功能:在controller类的方法的参数上加上@Valid属性

4.校验失败的处理:

  • 第一种:单独处理
  1. public R save(@Valid @RequestBody BrandEntity brand,BindingResult result){
  2. if(result.hasErrors()){
  3. Map<String,String> map = new HashMap<>();
  4. //1、获取校验的错误结果
  5. result.getFieldErrors().forEach((item)->{
  6. //FieldError 获取到错误提示
  7. String message = item.getDefaultMessage();
  8. //获取错误的属性的名字
  9. String field = item.getField();
  10. map.put(field,message);
  11. });
  12. return R.error(400,"提交的数据不合法").put("data",map);
  13. }else {
  14. brandService.save(brand);
  15. }
  16. return R.ok();
  17. }
  • 第二种,抛出异常后统一处理
  1. 定义@RestControllerAdvice处理请求异常类
  2. @ExceptionHandler(value= xxx.class)注解根据异常类型标注在方法上,编写处理逻辑
  1. @Slf4j
  2. @RestControllerAdvice
  3. public class ExceptionControllerAdvice {
  4. @ExceptionHandler(value= MethodArgumentNotValidException.class)
  5. public R handleValidException(MethodArgumentNotValidException e){
  6. log.error("数据校验出现问题{},异常类型:{}",e.getMessage(),e.getClass());
  7. BindingResult bindingResult = e.getBindingResult();
  8. Map<String,String> errorMap = new HashMap<>();
  9. bindingResult.getFieldErrors().forEach((error)->{
  10. //存储校验字段名,以及校验字段失败提示
  11. errorMap.put(error.getField(),error.getDefaultMessage());
  12. });
  13. return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",errorMap);
  14. }
  15. @ExceptionHandler(value = Throwable.class)
  16. public R handleException(Throwable throwable){
  17. log.error("错误:",throwable);
  18. return R.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(),BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
  19. }
  20. }
  1. 定义异常枚举类
  1. public enum BizCodeEnume {
  2. UNKNOW_EXCEPTION(10000,"系统未知异常"),
  3. VAILD_EXCEPTION(10001,"参数格式校验失败");
  4. private int code;
  5. private String msg;
  6. BizCodeEnume(int code,String msg){
  7. this.code = code;
  8. this.msg = msg;
  9. }
  10. public int getCode() {
  11. return code;
  12. }
  13. public String getMsg() {
  14. return msg;
  15. }
  16. }
  1. @NotNull

    只要不为空,校验任意类型

    The annotated element must not be {@code null}.

    Accepts any type.

  2. @NotBlank

    至少有一个非空字符,校验字符

    The annotated element must not be {@code null} and must contain at least one

    non-whitespace character. Accepts {@code CharSequence}.

  3. @NotEmpty

    非空,也不能内容为空,校验字符,集合,数组

    The annotated element must not be {@code null} nor empty. Supported types are:

    {@code CharSequence} (length of character sequence is evaluated)

    {@code Collection} (collection size is evaluated)

    {@code Map} (map size is evaluated)

    Array (array length is evaluated)

步骤:

  1. 在校验注解上加上groups = {xxx.class, ...}属性,值可以是任意interface接口,例如

    @URL(message = "logo必须是一个合法的url地址",groups={AddGroup.class,UpdateGroup.class})

  2. 在开启校验处,将@Valid注解改为@Validated({xxx.class}),例如@Validated({AddGroup.class})就表示只校验该组的属性;

    注意:未添加任何分组的校验将会无效,开启娇艳的时候i如果添加了分组信息,那么只会校验同样页添加了该分组的属性。

1)、编写一个自定义的校验注解

  1. @Documented
  2. @Constraint(validatedBy = { })
  3. @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
  4. @Retention(RUNTIME)
  5. public @interface ListValue {
  6. String message() default "{com.lx.common.valid.ListValue.message}";
  7. Class<?>[] groups() default { };
  8. Class<? extends Payload>[] payload() default { };
  9. int[] vals() default { };
  10. }

2)、编写配置文件ValidationMessages.properties,给自定义的校验配置校验失败的信息

  1. com.lx.common.valid.ListValue.message=显示状态只能为10

3)、编写一个自定义的校验器 ConstraintValidator

​ 实现ConstraintValidator接口,第一个参数为绑定的校验注解名,第二个参数为校验的属性类型,完成初始化与判断方法。

  1. public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
  2. private Set<Integer> set = new HashSet<>();
  3. /**
  4. * @Description: 根据注解中的属性初始化
  5. * @Param0: constraintAnnotation
  6. **/
  7. @Override
  8. public void initialize(ListValue constraintAnnotation) {
  9. int[] vals = constraintAnnotation.vals();
  10. for (int val:vals) {
  11. set.add(val);
  12. }
  13. }
  14. /**
  15. * @Description: 判断校验是否成功
  16. * @Param0: value 被校验值
  17. * @Param1: context
  18. **/
  19. @Override
  20. public boolean isValid(Integer value, ConstraintValidatorContext context) {
  21. return set.contains(value);
  22. }
  23. }

4)、关联自定义的校验器和自定义的校验注解

  1. @Constraint(validatedBy = { ListValueConstraintValidator.class })

5)、使用

  1. @NotNull(groups = {AddGroup.class, UpdateGroup.class})
  2. @ListValue(vals = {0,1},groups = {AddGroup.class,UpdateGroup.class})
  3. private Integer showStatus;

controller

  1. /**
  2. * 保存
  3. */
  4. @RequestMapping("/save")
  5. public R save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand){
  6. brandService.save(brand);
  7. return R.ok();
  8. }
  9. /**
  10. * 修改
  11. */
  12. @RequestMapping("/update")
  13. public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand){
  14. brandService.updateById(brand);
  15. return R.ok();
  16. }

entity

  1. @Data
  2. @TableName("pms_brand")
  3. public class BrandEntity implements Serializable {
  4. private static final long serialVersionUID = 1L;
  5. /**
  6. * 品牌id
  7. */
  8. @NotNull(message = "修改必须指定品牌id",groups = {UpdateGroup.class})
  9. @Null(message = "新增不能指定id",groups = {AddGroup.class})
  10. @TableId
  11. private Long brandId;
  12. /**
  13. * 品牌名
  14. */
  15. @NotBlank(message = "品牌名必须提交",groups = {AddGroup.class,UpdateGroup.class})
  16. private String name;
  17. /**
  18. * 品牌logo地址
  19. */
  20. @URL(message = "logo必须是一个合法的url地址",groups={AddGroup.class,UpdateGroup.class})
  21. private String logo;
  22. /**
  23. * 介绍
  24. */
  25. private String descript;
  26. /**
  27. * 显示状态[0-不显示;1-显示]
  28. */
  29. @NotNull(groups = {AddGroup.class, UpdateGroup.class})
  30. @ListValue(vals = {0,1},groups = {AddGroup.class,UpdateGroup.class})
  31. private Integer showStatus;
  32. /**
  33. * 检索首字母
  34. */
  35. @NotEmpty(groups={AddGroup.class})
  36. @Pattern(regexp="^[a-zA-Z]$",message = "检索首字母必须是一个字母",groups={AddGroup.class,UpdateGroup.class})
  37. private String firstLetter;
  38. /**
  39. * 排序
  40. */
  41. @NotNull(groups={AddGroup.class})
  42. @Min(value = 0,message = "排序必须大于等于0",groups={AddGroup.class,UpdateGroup.class})
  43. private Integer sort;
  44. }

测试1:

image-20200520180447340

测试2:

image-20200520180816926

版权声明:本文为jklixin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/jklixin/p/12925234.html