springboot:validator之自定义注解校验
创始人
2024-03-20 09:56:54

文章目录

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

springboot:validator之自定义注解校验

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

一、依赖

		javax.validationvalidation-api2.0.1.Finalorg.hibernate.validatorhibernate-validator6.0.16.Finalcompile

二、自定义注解

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

加入到需要校验的字段上

 /*** 	信号属性(AI,DI,Other,DO)* 	AI:普通数据* 	DI:输入开关* 	DO:输出开关*/@NotBlank(message = "信号属性不可以为空")@ContainsDataValid(message = "信号属性不正确",values = {"AI","DI","Other","DO"})private String propertyType;

自定义注解

package com.mye.cloudboxdcim.framework.engine.validator.anno;import com.mye.cloudboxdcim.framework.engine.validator.method.ContainsDataValidator;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;/*** @ClassName ContainsValidata* @Description 自定义注解,判断枚举是否包含* @Author hl* @Date 2022/11/3 15:52* @Version 1.0*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {ContainsDataValidator.class})// 标明由哪个类执行校验逻辑
public @interface ContainsDataValid {// 校验出错时默认返回的消息String message() default "字段值不正确";Class[] groups() default { };Class[] payload() default { };String[] values() default {}; // 指定值/*** 同一个元素上指定多个该注解时使用*/@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)@Documentedpublic @interface List {ContainsDataValid[] value();}}

具体实现类

package com.mye.cloudboxdcim.framework.engine.validator.method;import cn.hutool.core.util.StrUtil;
import com.mye.cloudboxdcim.framework.engine.validator.anno.ContainsDataValid;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class ContainsDataValidator implements ConstraintValidator {// 全局变量存放值集合private List values = new ArrayList<>();// 注解初始化时执行@Overridepublic void initialize(ContainsDataValid constraintAnnotation) {// 获取注解中的值String[] strList = constraintAnnotation.values();// 赋值给全局变量values = Arrays.stream(strList).collect(Collectors.toList());}// 自定义的校验规则@Overridepublic boolean isValid(String o, ConstraintValidatorContext constraintValidatorContext) {// o 为实体属性的值// 判断值是否属于集合中的元素,true 检验通过,false校验不通过if (StrUtil.isBlank(o)){return true;}return values.contains(o.trim());}
}

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

加入到需要校验的字段上

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

自定义注解

package com.mye.cloudboxdcim.framework.engine.validator.anno;import com.mye.cloudboxdcim.framework.engine.validator.method.ContainsIntegerDataValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;/*** @ClassName ContainsIntegerDataValid* @Description 校验数字类型的枚举类* @Author hl* @Date 2022/11/7 16:58* @Version 1.0*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {ContainsIntegerDataValidator.class})// 标明由哪个类执行校验逻辑
public @interface ContainsIntegerDataValid {// 校验出错时默认返回的消息String message() default "字段值不正确";Class[] groups() default { };Class[] payload() default { };int[] values() default {}; // 指定值/*** 同一个元素上指定多个该注解时使用*/@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)@Documentedpublic @interface List {ContainsIntegerDataValid[] value();}
}

具体实现类

package com.mye.cloudboxdcim.framework.engine.validator.method;import cn.hutool.core.util.ObjectUtil;
import com.mye.cloudboxdcim.framework.engine.validator.anno.ContainsIntegerDataValid;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;/*** @ClassName ContainsIntegerDataValidator* @Description 自定义校验类* @Author hl* @Date 2022/11/7 16:59* @Version 1.0*/
public class ContainsIntegerDataValidator implements ConstraintValidator {private List list = new ArrayList<>();@Overridepublic void initialize(ContainsIntegerDataValid constraintAnnotation) {// 获取注解中的值int[] values= constraintAnnotation.values();// 赋值给全局变量list = Arrays.stream(values).boxed().collect(Collectors.toList());}@Overridepublic boolean isValid(Integer s, ConstraintValidatorContext constraintValidatorContext) {if (ObjectUtil.isNull(s)){return true;}return list.contains(s);}
}

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

加入到需要校验的字段上

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

自定义注解

package com.mye.cloudboxdcim.framework.engine.validator.anno;import com.mye.cloudboxdcim.framework.engine.validator.method.HaveNoBlankValidator;import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.NotBlank;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;/*** @ClassName HaveNoNullValid* @Description 自定义注解校验 String 类型的值* @Author hl* @Date 2022/11/7 14:39* @Version 1.0*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {HaveNoBlankValidator.class})// 标明由哪个类执行校验逻辑
public @interface HaveNoBlankValid {// 校验出错时默认返回的消息String message() default "字符串不合法";Class[] groups() default { };Class[] payload() default { };String value() default ""; // 指定值/*** 同一个元素上指定多个该注解时使用*/@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)@Documentedpublic @interface List {NotBlank[] value();}
}

具体实现类

package com.mye.cloudboxdcim.framework.engine.validator.method;import cn.hutool.core.util.StrUtil;
import com.mye.cloudboxdcim.framework.engine.validator.anno.HaveNoBlankValid;
import com.mye.cloudboxdcim.util.StringUtil;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashMap;
import java.util.Map;public class HaveNoBlankValidator implements ConstraintValidator {private String initValue = "";/*** @MethodName initialize* @Description  注解初始化时执行* @param haveNoBlankValid  自定义注解* @Author hl* @Date 17:05 17:05*/@Overridepublic void initialize(HaveNoBlankValid haveNoBlankValid) {// 获取注解中的值initValue = haveNoBlankValid.value();}/*** @MethodName isValid* @Description  自定义校验规则* @param value 具体值* @param context* @return: boolean true 通过校验 false 没有通过校验* @Author hl* @Date 17:04 17:04*/@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {// null 不做检验if (StrUtil.isBlank(value)) {//true 通过校验return true;}if (StrUtil.isNotBlank(initValue)){switch (initValue) {case "description"://检查描述长度return checkDescription(value);case "unit"://检查信号单位长度return checkUnit(value);case "enumConstant"://检查信号枚举值return checkEnumConstant(value);case "place":return checkCloudBoxPlace(value);}}return true;}private boolean checkCloudBoxPlace(String value) {return value.length() <= 50;}/*** @MethodName checkEnumConstant* @Description  检查信号枚举值* @param value 具体值* @return: boolean* @Author hl* @Date 17:31 17:31*/private boolean checkEnumConstant(String value) {String[] enumConstants = value.split(",");if (enumConstants.length < 1 ) {return false;}Map hashMap = new HashMap<>();for (String data : enumConstants) {if (!data.contains(":")) {return false;}String[] map = data.split(":");if (map.length != 2) {return false;}try {Integer key = Integer.valueOf(map[0]);if (hashMap.containsKey(key)) {return false;}hashMap.put(key, map[1]);} catch (Exception e) {return false;}if (StringUtil.isBlank(map[1])) {return false;}}return true;}/*** @MethodName checkUnit* @Description  检查单位长度* @param value 具体值* @return: boolean* @Author hl* @Date 17:09 17:09*/private boolean checkUnit(String value) {return value.length() <= 10;}/*** @MethodName checkDescription* @Description  检查描述长度* @param value 具体值* @return: java.lang.Boolean* @Author hl* @Date 16:51 16:51*/private Boolean checkDescription(String value) {return value.length() <= 200;}
}

4、校验不为必填的数字

加入到需要校验的字段上

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

自定义注解

package com.mye.cloudboxdcim.framework.engine.validator.anno;import com.mye.cloudboxdcim.framework.engine.validator.method.HaveNoNullValidator;import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;/*** @ClassName HaveNoNullValid* @Description 自定义注解校验 Integer 类型的值* @Author hl* @Date 2022/11/7 14:39* @Version 1.0*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {HaveNoNullValidator.class})// 标明由哪个类执行校验逻辑
public @interface HaveNoNullValid {// 校验出错时默认返回的消息String message() default "数据不合法";Class[] groups() default { };Class[] payload() default { };String value() default ""; // 指定值/*** 同一个元素上指定多个该注解时使用*/@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)@Documentedpublic @interface List {NotNull value();}
}

具体实现类

package com.mye.cloudboxdcim.framework.engine.validator.method;import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.mye.cloudboxdcim.framework.engine.validator.anno.HaveNoNullValid;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;/*** @ClassName HaveNoNullValidator* @Description 实现注解 HaveNoNullValid 的具体实现逻辑* @Author hl* @Date 2022/11/7 14:41* @Version 1.0*/
public class HaveNoNullValidator implements ConstraintValidator {private String initValue = "";@Overridepublic void initialize(HaveNoNullValid haveNoNullValid) {// 获取注解中的值initValue = haveNoNullValid.value();}@Overridepublic boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {// null 不做检验if (ObjectUtil.isNull(value)) {//true 通过校验return true;}if (StrUtil.isNotBlank(initValue)){switch (initValue) {case "state":return checkFlashState(value);case "period":return checkPeriod(value);}}return true;}private boolean checkPeriod(Integer value) {return value >= 1 && value <= 3600;}private boolean checkFlashState(Integer value) {return value == 0 || value == 1;}
}

5、校验Integer 类型的集合

加入到需要校验的字段上

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

自定义注解

package com.mye.cloudboxdcim.framework.engine.validator.anno;import com.mye.cloudboxdcim.framework.engine.validator.method.VerifyIntegerCollectionDataValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;/*** @ClassName VerifyCollectionDataValid* @Description 自定义注解校验 Integer 类型的集合数据是否合法* @Author hl* @Date 2022/11/8 10:25* @Version 1.0*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {VerifyIntegerCollectionDataValidator.class})// 标明由哪个类执行校验逻辑
public @interface VerifyIntegerCollectionDataValid {// 校验出错时默认返回的消息String message() default "字段值不正确";Class[] groups() default { };Class[] payload() default { };int[] values() default {}; // 指定值/*** 同一个元素上指定多个该注解时使用*/@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })@Retention(RUNTIME)@Documentedpublic @interface List {VerifyIntegerCollectionDataValid[] value();}
}

具体实现类

package com.mye.cloudboxdcim.framework.engine.validator.method;import cn.hutool.core.util.ObjectUtil;
import com.mye.cloudboxdcim.framework.engine.validator.anno.ContainsIntegerDataValid;
import com.mye.cloudboxdcim.framework.engine.validator.anno.VerifyIntegerCollectionDataValid;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;/*** @ClassName VerifyIntegerCollectionDataValidator* @Description 自定义校验类,校验List 数据是否合法* @Author hl* @Date 2022/11/8 10:27* @Version 1.0*/
public class VerifyIntegerCollectionDataValidator implements ConstraintValidator> {private List list = new ArrayList<>();@Overridepublic void initialize(VerifyIntegerCollectionDataValid verifyIntegerCollectionDataValid) {// 获取注解中的值int[] values= verifyIntegerCollectionDataValid.values();// 赋值给全局变量list = Arrays.stream(values).boxed().collect(Collectors.toList());}@Overridepublic boolean isValid(List integers, ConstraintValidatorContext constraintValidatorContext) {if (ObjectUtil.isNull(integers)){return true;}Integer level = integers.stream().filter(Objects::nonNull).filter(s -> !list.contains(s)).findAny().orElse(null);return ObjectUtil.isNull(level);}
}

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...