springboot:validator之自定义注解校验

电玩女神 2024-03-31 15:09 146阅读 0赞

文章目录

  • springboot:validator之自定义注解校验
    • 一、依赖
    • 二、自定义注解
      • 1、校验字符串类型的枚举类
      • 2、校验数字类型的枚举类
      • 3、校验不为必填的字符串
      • 4、校验不为必填的数字
      • 5、校验Integer 类型的集合

springboot:validator之自定义注解校验

validator的基本使用请查看文章:SpringBoot:参数校验的使用(validator)

一、依赖

  1. <dependency>
  2. <groupId>javax.validation</groupId>
  3. <artifactId>validation-api</artifactId>
  4. <version>2.0.1.Final</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.hibernate.validator</groupId>
  8. <artifactId>hibernate-validator</artifactId>
  9. <version>6.0.16.Final</version>
  10. <scope>compile</scope>
  11. </dependency>

二、自定义注解

1、校验字符串类型的枚举类

加入到需要校验的字段上

  1. /**
  2. * 信号属性(AI,DI,Other,DO)
  3. * AI:普通数据
  4. * DI:输入开关
  5. * DO:输出开关
  6. */
  7. @NotBlank(message = "信号属性不可以为空")
  8. @ContainsDataValid(message = "信号属性不正确",values = {
  9. "AI","DI","Other","DO"})
  10. private String propertyType;

自定义注解

  1. package com.mye.cloudboxdcim.framework.engine.validator.anno;
  2. import com.mye.cloudboxdcim.framework.engine.validator.method.ContainsDataValidator;
  3. import javax.validation.Constraint;
  4. import javax.validation.Payload;
  5. import java.lang.annotation.Documented;
  6. import java.lang.annotation.Retention;
  7. import java.lang.annotation.Target;
  8. import static java.lang.annotation.ElementType.*;
  9. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  10. /**
  11. * @ClassName ContainsValidata
  12. * @Description 自定义注解,判断枚举是否包含
  13. * @Author hl
  14. * @Date 2022/11/3 15:52
  15. * @Version 1.0
  16. */
  17. @Target({
  18. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
  19. @Retention(RUNTIME)
  20. @Documented
  21. @Constraint(validatedBy = {
  22. ContainsDataValidator.class})// 标明由哪个类执行校验逻辑
  23. public @interface ContainsDataValid {
  24. // 校验出错时默认返回的消息
  25. String message() default "字段值不正确";
  26. Class<?>[] groups() default {
  27. };
  28. Class<? extends Payload>[] payload() default {
  29. };
  30. String[] values() default {
  31. }; // 指定值
  32. /**
  33. * 同一个元素上指定多个该注解时使用
  34. */
  35. @Target({
  36. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
  37. @Retention(RUNTIME)
  38. @Documented
  39. public @interface List {
  40. ContainsDataValid[] value();
  41. }
  42. }

具体实现类

  1. package com.mye.cloudboxdcim.framework.engine.validator.method;
  2. import cn.hutool.core.util.StrUtil;
  3. import com.mye.cloudboxdcim.framework.engine.validator.anno.ContainsDataValid;
  4. import javax.validation.ConstraintValidator;
  5. import javax.validation.ConstraintValidatorContext;
  6. import java.util.ArrayList;
  7. import java.util.Arrays;
  8. import java.util.List;
  9. import java.util.stream.Collectors;
  10. public class ContainsDataValidator implements ConstraintValidator<ContainsDataValid,String> {
  11. // 全局变量存放值集合
  12. private List<String> values = new ArrayList<>();
  13. // 注解初始化时执行
  14. @Override
  15. public void initialize(ContainsDataValid constraintAnnotation) {
  16. // 获取注解中的值
  17. String[] strList = constraintAnnotation.values();
  18. // 赋值给全局变量
  19. values = Arrays.stream(strList).collect(Collectors.toList());
  20. }
  21. // 自定义的校验规则
  22. @Override
  23. public boolean isValid(String o, ConstraintValidatorContext constraintValidatorContext) {
  24. // o 为实体属性的值
  25. // 判断值是否属于集合中的元素,true 检验通过,false校验不通过
  26. if (StrUtil.isBlank(o)){
  27. return true;
  28. }
  29. return values.contains(o.trim());
  30. }
  31. }

2、校验数字类型的枚举类

加入到需要校验的字段上

  1. /**
  2. * 优先级(最高2,高1,中0 -1低,-2最低)
  3. */
  4. @NotNull(message = "优先级不能为空")
  5. @ContainsIntegerDataValid(message = "优先级不合法",values = {
  6. -2,-1,0,1,2})
  7. private Integer priority;

自定义注解

  1. package com.mye.cloudboxdcim.framework.engine.validator.anno;
  2. import com.mye.cloudboxdcim.framework.engine.validator.method.ContainsIntegerDataValidator;
  3. import javax.validation.Constraint;
  4. import javax.validation.Payload;
  5. import java.lang.annotation.Documented;
  6. import java.lang.annotation.Retention;
  7. import java.lang.annotation.Target;
  8. import static java.lang.annotation.ElementType.*;
  9. import static java.lang.annotation.ElementType.TYPE_USE;
  10. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  11. /**
  12. * @ClassName ContainsIntegerDataValid
  13. * @Description 校验数字类型的枚举类
  14. * @Author hl
  15. * @Date 2022/11/7 16:58
  16. * @Version 1.0
  17. */
  18. @Target({
  19. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
  20. @Retention(RUNTIME)
  21. @Documented
  22. @Constraint(validatedBy = {
  23. ContainsIntegerDataValidator.class})// 标明由哪个类执行校验逻辑
  24. public @interface ContainsIntegerDataValid {
  25. // 校验出错时默认返回的消息
  26. String message() default "字段值不正确";
  27. Class<?>[] groups() default {
  28. };
  29. Class<? extends Payload>[] payload() default {
  30. };
  31. int[] values() default {
  32. }; // 指定值
  33. /**
  34. * 同一个元素上指定多个该注解时使用
  35. */
  36. @Target({
  37. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
  38. @Retention(RUNTIME)
  39. @Documented
  40. public @interface List {
  41. ContainsIntegerDataValid[] value();
  42. }
  43. }

具体实现类

  1. package com.mye.cloudboxdcim.framework.engine.validator.method;
  2. import cn.hutool.core.util.ObjectUtil;
  3. import com.mye.cloudboxdcim.framework.engine.validator.anno.ContainsIntegerDataValid;
  4. import javax.validation.ConstraintValidator;
  5. import javax.validation.ConstraintValidatorContext;
  6. import java.util.ArrayList;
  7. import java.util.Arrays;
  8. import java.util.List;
  9. import java.util.stream.Collectors;
  10. /**
  11. * @ClassName ContainsIntegerDataValidator
  12. * @Description 自定义校验类
  13. * @Author hl
  14. * @Date 2022/11/7 16:59
  15. * @Version 1.0
  16. */
  17. public class ContainsIntegerDataValidator implements ConstraintValidator<ContainsIntegerDataValid,Integer> {
  18. private List<Integer> list = new ArrayList<>();
  19. @Override
  20. public void initialize(ContainsIntegerDataValid constraintAnnotation) {
  21. // 获取注解中的值
  22. int[] values= constraintAnnotation.values();
  23. // 赋值给全局变量
  24. list = Arrays.stream(values).boxed().collect(Collectors.toList());
  25. }
  26. @Override
  27. public boolean isValid(Integer s, ConstraintValidatorContext constraintValidatorContext) {
  28. if (ObjectUtil.isNull(s)){
  29. return true;
  30. }
  31. return list.contains(s);
  32. }
  33. }

3、校验不为必填的字符串

加入到需要校验的字段上

  1. /**
  2. * 描述信息
  3. */
  4. @HaveNoBlankValid(message = "描述长度最大为200",value = "description")
  5. private String description;

自定义注解

  1. package com.mye.cloudboxdcim.framework.engine.validator.anno;
  2. import com.mye.cloudboxdcim.framework.engine.validator.method.HaveNoBlankValidator;
  3. import javax.validation.Constraint;
  4. import javax.validation.Payload;
  5. import javax.validation.constraints.NotBlank;
  6. import java.lang.annotation.Documented;
  7. import java.lang.annotation.Retention;
  8. import java.lang.annotation.Target;
  9. import static java.lang.annotation.ElementType.*;
  10. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  11. /**
  12. * @ClassName HaveNoNullValid
  13. * @Description 自定义注解校验 String 类型的值
  14. * @Author hl
  15. * @Date 2022/11/7 14:39
  16. * @Version 1.0
  17. */
  18. @Target({
  19. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
  20. @Retention(RUNTIME)
  21. @Documented
  22. @Constraint(validatedBy = {
  23. HaveNoBlankValidator.class})// 标明由哪个类执行校验逻辑
  24. public @interface HaveNoBlankValid {
  25. // 校验出错时默认返回的消息
  26. String message() default "字符串不合法";
  27. Class<?>[] groups() default {
  28. };
  29. Class<? extends Payload>[] payload() default {
  30. };
  31. String value() default ""; // 指定值
  32. /**
  33. * 同一个元素上指定多个该注解时使用
  34. */
  35. @Target({
  36. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
  37. @Retention(RUNTIME)
  38. @Documented
  39. public @interface List {
  40. NotBlank[] value();
  41. }
  42. }

具体实现类

  1. package com.mye.cloudboxdcim.framework.engine.validator.method;
  2. import cn.hutool.core.util.StrUtil;
  3. import com.mye.cloudboxdcim.framework.engine.validator.anno.HaveNoBlankValid;
  4. import com.mye.cloudboxdcim.util.StringUtil;
  5. import javax.validation.ConstraintValidator;
  6. import javax.validation.ConstraintValidatorContext;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. public class HaveNoBlankValidator implements ConstraintValidator<HaveNoBlankValid, String> {
  10. private String initValue = "";
  11. /**
  12. * @MethodName initialize
  13. * @Description 注解初始化时执行
  14. * @param haveNoBlankValid 自定义注解
  15. * @Author hl
  16. * @Date 17:05 17:05
  17. */
  18. @Override
  19. public void initialize(HaveNoBlankValid haveNoBlankValid) {
  20. // 获取注解中的值
  21. initValue = haveNoBlankValid.value();
  22. }
  23. /**
  24. * @MethodName isValid
  25. * @Description 自定义校验规则
  26. * @param value 具体值
  27. * @param context
  28. * @return: boolean true 通过校验 false 没有通过校验
  29. * @Author hl
  30. * @Date 17:04 17:04
  31. */
  32. @Override
  33. public boolean isValid(String value, ConstraintValidatorContext context) {
  34. // null 不做检验
  35. if (StrUtil.isBlank(value)) {
  36. //true 通过校验
  37. return true;
  38. }
  39. if (StrUtil.isNotBlank(initValue)){
  40. switch (initValue) {
  41. case "description":
  42. //检查描述长度
  43. return checkDescription(value);
  44. case "unit":
  45. //检查信号单位长度
  46. return checkUnit(value);
  47. case "enumConstant":
  48. //检查信号枚举值
  49. return checkEnumConstant(value);
  50. case "place":
  51. return checkCloudBoxPlace(value);
  52. }
  53. }
  54. return true;
  55. }
  56. private boolean checkCloudBoxPlace(String value) {
  57. return value.length() <= 50;
  58. }
  59. /**
  60. * @MethodName checkEnumConstant
  61. * @Description 检查信号枚举值
  62. * @param value 具体值
  63. * @return: boolean
  64. * @Author hl
  65. * @Date 17:31 17:31
  66. */
  67. private boolean checkEnumConstant(String value) {
  68. String[] enumConstants = value.split(",");
  69. if (enumConstants.length < 1 ) {
  70. return false;
  71. }
  72. Map<Integer, String> hashMap = new HashMap<>();
  73. for (String data : enumConstants) {
  74. if (!data.contains(":")) {
  75. return false;
  76. }
  77. String[] map = data.split(":");
  78. if (map.length != 2) {
  79. return false;
  80. }
  81. try {
  82. Integer key = Integer.valueOf(map[0]);
  83. if (hashMap.containsKey(key)) {
  84. return false;
  85. }
  86. hashMap.put(key, map[1]);
  87. } catch (Exception e) {
  88. return false;
  89. }
  90. if (StringUtil.isBlank(map[1])) {
  91. return false;
  92. }
  93. }
  94. return true;
  95. }
  96. /**
  97. * @MethodName checkUnit
  98. * @Description 检查单位长度
  99. * @param value 具体值
  100. * @return: boolean
  101. * @Author hl
  102. * @Date 17:09 17:09
  103. */
  104. private boolean checkUnit(String value) {
  105. return value.length() <= 10;
  106. }
  107. /**
  108. * @MethodName checkDescription
  109. * @Description 检查描述长度
  110. * @param value 具体值
  111. * @return: java.lang.Boolean
  112. * @Author hl
  113. * @Date 16:51 16:51
  114. */
  115. private Boolean checkDescription(String value) {
  116. return value.length() <= 200;
  117. }
  118. }

4、校验不为必填的数字

加入到需要校验的字段上

  1. /**
  2. * 闪断周期(单位秒)
  3. */
  4. @HaveNoNullValid(message = "闪断周期是 1~3600",value = "period")
  5. private Integer flashPeriod;

自定义注解

  1. package com.mye.cloudboxdcim.framework.engine.validator.anno;
  2. import com.mye.cloudboxdcim.framework.engine.validator.method.HaveNoNullValidator;
  3. import javax.validation.Constraint;
  4. import javax.validation.Payload;
  5. import javax.validation.constraints.NotBlank;
  6. import javax.validation.constraints.NotNull;
  7. import java.lang.annotation.Documented;
  8. import java.lang.annotation.Retention;
  9. import java.lang.annotation.Target;
  10. import static java.lang.annotation.ElementType.*;
  11. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  12. /**
  13. * @ClassName HaveNoNullValid
  14. * @Description 自定义注解校验 Integer 类型的值
  15. * @Author hl
  16. * @Date 2022/11/7 14:39
  17. * @Version 1.0
  18. */
  19. @Target({
  20. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
  21. @Retention(RUNTIME)
  22. @Documented
  23. @Constraint(validatedBy = {
  24. HaveNoNullValidator.class})// 标明由哪个类执行校验逻辑
  25. public @interface HaveNoNullValid {
  26. // 校验出错时默认返回的消息
  27. String message() default "数据不合法";
  28. Class<?>[] groups() default {
  29. };
  30. Class<? extends Payload>[] payload() default {
  31. };
  32. String value() default ""; // 指定值
  33. /**
  34. * 同一个元素上指定多个该注解时使用
  35. */
  36. @Target({
  37. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
  38. @Retention(RUNTIME)
  39. @Documented
  40. public @interface List {
  41. NotNull value();
  42. }
  43. }

具体实现类

  1. package com.mye.cloudboxdcim.framework.engine.validator.method;
  2. import cn.hutool.core.util.ObjectUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import com.mye.cloudboxdcim.framework.engine.validator.anno.HaveNoNullValid;
  5. import javax.validation.ConstraintValidator;
  6. import javax.validation.ConstraintValidatorContext;
  7. /**
  8. * @ClassName HaveNoNullValidator
  9. * @Description 实现注解 HaveNoNullValid 的具体实现逻辑
  10. * @Author hl
  11. * @Date 2022/11/7 14:41
  12. * @Version 1.0
  13. */
  14. public class HaveNoNullValidator implements ConstraintValidator<HaveNoNullValid, Integer> {
  15. private String initValue = "";
  16. @Override
  17. public void initialize(HaveNoNullValid haveNoNullValid) {
  18. // 获取注解中的值
  19. initValue = haveNoNullValid.value();
  20. }
  21. @Override
  22. public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
  23. // null 不做检验
  24. if (ObjectUtil.isNull(value)) {
  25. //true 通过校验
  26. return true;
  27. }
  28. if (StrUtil.isNotBlank(initValue)){
  29. switch (initValue) {
  30. case "state":
  31. return checkFlashState(value);
  32. case "period":
  33. return checkPeriod(value);
  34. }
  35. }
  36. return true;
  37. }
  38. private boolean checkPeriod(Integer value) {
  39. return value >= 1 && value <= 3600;
  40. }
  41. private boolean checkFlashState(Integer value) {
  42. return value == 0 || value == 1;
  43. }
  44. }

5、校验Integer 类型的集合

加入到需要校验的字段上

  1. /**
  2. * 告警级别(默认0提示,1次要,2重要,3紧急)
  3. */
  4. @NotEmpty(message = "告警级别集合不能为空")
  5. @VerifyIntegerCollectionDataValid(message = "告警级别不合法",values = {
  6. 0,1,2,3})
  7. private List<Integer> levelList;

自定义注解

  1. package com.mye.cloudboxdcim.framework.engine.validator.anno;
  2. import com.mye.cloudboxdcim.framework.engine.validator.method.VerifyIntegerCollectionDataValidator;
  3. import javax.validation.Constraint;
  4. import javax.validation.Payload;
  5. import java.lang.annotation.Documented;
  6. import java.lang.annotation.Retention;
  7. import java.lang.annotation.Target;
  8. import static java.lang.annotation.ElementType.*;
  9. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  10. /**
  11. * @ClassName VerifyCollectionDataValid
  12. * @Description 自定义注解校验 Integer 类型的集合数据是否合法
  13. * @Author hl
  14. * @Date 2022/11/8 10:25
  15. * @Version 1.0
  16. */
  17. @Target({
  18. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
  19. @Retention(RUNTIME)
  20. @Documented
  21. @Constraint(validatedBy = {
  22. VerifyIntegerCollectionDataValidator.class})// 标明由哪个类执行校验逻辑
  23. public @interface VerifyIntegerCollectionDataValid {
  24. // 校验出错时默认返回的消息
  25. String message() default "字段值不正确";
  26. Class<?>[] groups() default {
  27. };
  28. Class<? extends Payload>[] payload() default {
  29. };
  30. int[] values() default {
  31. }; // 指定值
  32. /**
  33. * 同一个元素上指定多个该注解时使用
  34. */
  35. @Target({
  36. METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
  37. @Retention(RUNTIME)
  38. @Documented
  39. public @interface List {
  40. VerifyIntegerCollectionDataValid[] value();
  41. }
  42. }

具体实现类

  1. package com.mye.cloudboxdcim.framework.engine.validator.method;
  2. import cn.hutool.core.util.ObjectUtil;
  3. import com.mye.cloudboxdcim.framework.engine.validator.anno.ContainsIntegerDataValid;
  4. import com.mye.cloudboxdcim.framework.engine.validator.anno.VerifyIntegerCollectionDataValid;
  5. import javax.validation.ConstraintValidator;
  6. import javax.validation.ConstraintValidatorContext;
  7. import java.util.ArrayList;
  8. import java.util.Arrays;
  9. import java.util.List;
  10. import java.util.Objects;
  11. import java.util.stream.Collectors;
  12. /**
  13. * @ClassName VerifyIntegerCollectionDataValidator
  14. * @Description 自定义校验类,校验List<Integer> 数据是否合法
  15. * @Author hl
  16. * @Date 2022/11/8 10:27
  17. * @Version 1.0
  18. */
  19. public class VerifyIntegerCollectionDataValidator implements ConstraintValidator<VerifyIntegerCollectionDataValid, List<Integer>> {
  20. private List<Integer> list = new ArrayList<>();
  21. @Override
  22. public void initialize(VerifyIntegerCollectionDataValid verifyIntegerCollectionDataValid) {
  23. // 获取注解中的值
  24. int[] values= verifyIntegerCollectionDataValid.values();
  25. // 赋值给全局变量
  26. list = Arrays.stream(values).boxed().collect(Collectors.toList());
  27. }
  28. @Override
  29. public boolean isValid(List<Integer> integers, ConstraintValidatorContext constraintValidatorContext) {
  30. if (ObjectUtil.isNull(integers)){
  31. return true;
  32. }
  33. Integer level = integers.stream().filter(Objects::nonNull).filter(s -> !list.contains(s)).findAny().orElse(null);
  34. return ObjectUtil.isNull(level);
  35. }
  36. }

发表评论

表情:
评论列表 (有 0 条评论,146人围观)

还没有评论,来说两句吧...

相关阅读

    相关 定义校验注解框架

    自定义校验注解框架 经过[上一篇文章][Link 1]的学习大家对校验注解有了初步认识,如果没有了解[上一篇文章][Link 1]或对注解了解不深的小朋友请`认真`学习!

    相关 java定义校验注解

    随着业务的日趋复杂。我们对客户端传来的参数校验也越来越多。这么多的校验如果都写在业务逻辑中,业务代码看起来会很乱。 找时间学习了一下java的注解。特在此记录一下学习过程。

    相关 JSR303定义校验注解

     一 点睛 1 编写一个自定校验注解 2 编写一个自定义的校验器 3 关联自定义校验器和自定义的校验注解 二 实战 1 导入依赖 <!-- 自定义校