在SpringBoot中工程中通常需要对数据作校验,而有些时候前端传入的参数只能是特定值。可以考虑定义一个枚举类
工程
pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
校验定义
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = ForEnumValidator.class)
public @interface ForEnum {
/**
* @return 提示内容
*/
String message() default "必须在指定范围 {value}";
/**
* 枚举类
*/
Class<? extends Enum<?>> enumClass();
/**
* 获取指定的方法名。此方法必须是无参方法
*/
String methodName() default "name";
/**
* @return 分组
*/
Class<?>[] groups() default {};
/**
* @return Payload 数组
*/
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@interface List {
ForEnum[] value();
}
}
// 这里将泛型定义为Object,可以对任意数据类型作校验
public class ForEnumValidator implements ConstraintValidator<ForEnum, Object> {
// 枚举类型
private Class<? extends Enum<?>> enumClass;
// 获取值方法
private String methodName;
@Override
public void initialize(ForEnum annotation) {
enumClass = annotation.enumClass();
methodName = annotation.methodName();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
Method method = ReflectionUtils.findMethod(enumClass, methodName);
return Arrays.stream(enumClass.getEnumConstants())
.map(item -> ReflectionUtils.invokeMethod(method, item))
.anyMatch(item -> item.equals(value));
}
}
测试
// 取值限定枚举类
public enum Color {
RED("红色", "red", 1),
GREEN("绿色", "green", 2),
BLANK("白色", "blank", 3),
YELLO("黄色", "yello", 4);
// 成员变量
private String name;
private int index;
private String title;
// 构造方法
Color(String name, String title, int index) {
this.name = name;
this.title = title;
this.index = index;
}
}
public class Person {
@ForEnum(enumClass = Color.class, methodName = "getTitle")
private String color;
@ForEnum(enumClass = Color.class, methodName = "getIndex")
private Integer age;
}
@RestController
public class DemoController {
@PostMapping("demo")
public Person person(@RequestBody @Valid Person person) {
return person;
}
}