当前位置:网站首页>Enum + Validation 的个人最佳实践 demo 分享
Enum + Validation 的个人最佳实践 demo 分享
2022-07-07 15:39:00 【小水牛...】
前言
很多场景中我们需要校验前端传来的参数是否属于某个 Enum 值,分享一段个人最佳实践的 demo:
Enum的最简声明@OfEnum & OfEnumValidatorTest suite
Enum 声明
通常 Enum 的声明是映射到对应的 DB 字段,个人实践是直接以 Enum Name 对应具体值,无需在 Enum 里包含释义信息等,比如 SexEnum 声明为 man woman 而不是类似 男("man") 女("woman"),这样也方便后续 Validator 类的编写
public enum SexEnum {
man
, woman
;
}
@OfEnum
@Constraint(
validatedBy = {
OfEnumValidator.class }
)
@Target({
ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface OfEnum {
Class<?> enumType();
String message() default "目标值必须是 ${enumType.simpleName} 类型的枚举值";
Class<?>[] groups() default {
};
Class<? extends Payload>[] payload() default {
};
}
该注解主要用于字段、参数上结合对应的 OfEnumValidator 执行校验
@Constraint注解声明对应的OfEnumValidator- 属性
enumType声明对应的枚举类型 message中引用EL表达式输出合理的校验信息
OfEnumValidator
public class OfEnumValidator implements ConstraintValidator<OfEnum, String> {
private List<String> enums;
// 枚举值初始化
@Override
public void initialize(OfEnum constraintAnnotation) {
enums = Optional.ofNullable(constraintAnnotation)
.map(OfEnum::enumType)
.filter(Class::isEnum)
.map(Class::getEnumConstants)
.map(arr -> Arrays.stream(arr)
.map(Object::toString)
.collect(Collectors.toList()))
.orElse(new ArrayList<>());
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
return !ObjectUtils.isEmpty(enums) && enums.contains(s);
}
}
OfEnumValidator 类负责执行 @OfEnum 注解对应的校验
- 基于指定的枚举类来初始化
enums属性,直接基于toString方法,因此前文推荐Enum的简单声明 isValid进行校验
Test
public class OfEnumTest {
ApplicationContextRunner runner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(ValidationAutoConfiguration.class));
@Validated
static class Handler {
public void handle(@OfEnum(enumType = SexEnum.class) String sex) {
}
}
static class Config {
@Bean
public Handler handler() {
return new Handler();
}
}
@Test
public void test() {
runner.withUserConfiguration(Config.class)
.run(context -> {
Handler bean = context.getBean(Handler.class);
bean.handle("man");
assertThatThrownBy(() -> bean.handle("error"))
.isInstanceOf(ConstraintViolationException.class)
.hasMessage("handle.sex: 目标值必须是 SexEnum 类型的枚举值");
});
}
}
针对 @OfEnum 注解的测试类:
- 基于
ApplicationContextRunner编写,很好用的测试辅助类,之前有分享 - 可以看到,当传入
SexEnum成员之外的值时,会抛出校验异常
总结
以上就是个人 Enum + Validation 的最佳实践分享
边栏推荐
- Nerf: the ultimate replacement for deepfake?
- mysql使用笔记一
- SlashData开发者工具榜首等你而定!!!
- From Devops to mlops: how do it tools evolve to AI tools?
- Smart logistics platform: make overseas warehouses smarter
- Pychart ide Download
- QT picture background color pixel processing method
- Skimage learning (2) -- RGB to grayscale, RGB to HSV, histogram matching
- skimage学习(3)——Gamma 和 log对比度调整、直方图均衡、为灰度图像着色
- MySQL usage notes 1
猜你喜欢
随机推荐
User defined view essential knowledge, Android R & D post must ask 30+ advanced interview questions
Sator launched Web3 game "satorspace" and launched hoobi
第二十四届中国科协湖南组委会调研课题组一行莅临麒麟信安调研考察
Repair method of firewall system crash and file loss, material cost 0 yuan
Sator推出Web3游戏“Satorspace” ,并上线Huobi
LeetCode 1626. The best team without contradiction
How to choose the appropriate automated testing tools?
Sator launched Web3 game "satorspace" and launched hoobi
Matplotlib绘制三维图形
Skimage learning (3) -- gamma and log contrast adjustment, histogram equalization, coloring gray images
LeetCode刷题day49
科普达人丨一文弄懂什么是云计算?
LeetCode 890(C#)
如何在软件研发阶段落地安全实践
LeetCode 120. Triangle minimum path and daily question
Rpcms method of obtaining articles under the specified classification
Process from creation to encapsulation of custom controls in QT to toolbar (I): creation of custom controls
服务器彻底坏了,无法修复,如何利用备份无损恢复成虚拟机?
Solidity 开发环境搭建
A tour of grpc:03 - proto serialization / deserialization








