前言:枚举校验器主要为了规范和统一使用固定的字符或者数字值
自定义参数校验器: https://blog.csdn.net/weixin_44953227/article/details/118752844
SpringBoot 版本 2.xx
依赖,一般使用添加了 spring-boot-starter-web
这个依赖就行了,他里面包含了数据校验的依赖,但还是在这里指明一下具体的依赖。
<!--数据校验-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
默认校验 getCode
方法获取的值。如果要校验枚举的其他字段,直接指定get方法。
package com.pro.annotation;
import com.pro.annotation.EnumValidtor;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* 校验入参是否为指定enum的值的注解
*/
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EnumValidtor.class})
@Documented
public @interface EnumValid {
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<?>[] target() default {};
String vaildField() default "getCode";
}
package com.pro.annotation;
import com.pro.annotation.EnumValid;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 校验入参是否为指定enum的值的实现方法
*/
public class EnumValidtor implements ConstraintValidator<EnumValid, Object> {
String vaildField;
Class<?>[] cls; //枚举类
@Override
public void initialize(EnumValid constraintAnnotation) {
cls = constraintAnnotation.target();
vaildField = constraintAnnotation.vaildField();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (value != null && value.toString().length() > 0 && cls.length > 0) {
for (Class<?> cl : cls
) {
try {
if (cl.isEnum()) {
//枚举类验证
Object[] objs = cl.getEnumConstants();
Method method = cl.getMethod("name");
for (Object obj : objs) {
Object code = method.invoke(obj, null);
if (value.equals(code.toString())) {
return true;
}
}
Method codeMethod = cl.getMethod(vaildField);
for (Object obj : objs) {
Object code = codeMethod.invoke(obj, null);
if (value.toString().equals(code.toString())) {
return true;
}
}
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
} else {
return true;
}
return false;
}
}
package com.pro.enums;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public enum GenderEnum {
/**
* 男
*/
MALE("MALE", "男"),
/**
* 女
*/
FEMALE("FEMALE", "女"),
;
private String code;
private String name;
GenderEnum(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
public static List<Map<String, Object>> toList() {
List<Map<String, Object>> result = new ArrayList<>();
for (GenderEnum e : GenderEnum.values()) {
Map<String, Object> map = new HashMap<>();
map.put("code", e.getCode());
map.put("value", e.getName());
result.add(map);
}
return result;
}
public static String getNameByCode(String code) {
for (GenderEnum value : values()) {
if (value.code.equals(code)) {
return value.name;
}
}
return "未知";
}
}
public class TestDTO {
// 默认校验 getCode 方法获取的值
@NotBlank(message = "性别不能为空")
@EnumValid(target = GenderEnum.class, message = "性别输入错误")
private String gender;
// 如果想校验枚举中其他的值, 直接指定 vaildField 方法的值即可, 下面是例子
@NotBlank(message = "性别不能为空")
@EnumValid(target = GenderEnum.class, vaildField = "getName", message = "性别输入错误")
private String gender2;
// 此处省略 get、set
}
这里说一句在 SpringBoot
中默认只会校验第一层实体类,如果想校验实体字段中的实体,需要在字段上加 @Valid
注解。
比如想校验 AddDTO
这个实体
public class TestDTO {
// 默认校验 getCode 方法获取的值
@NotBlank(message = "性别不能为空")
@EnumValid(target = GenderEnum.class, message = "性别输入错误")
private String gender;
/**
* 比如想让 AddDTO 中的字段上的注解校验也生效就必须加上 @Valid 这个注解
*/
@Valid
private List<AddDTO> addList;
// 此处省略 get、set
}
使用校验
@PostMapping("/update")
public Result updateAdverseRelation(@Validated @RequestBody TestDTO dto) {
}