当前位置:网站首页>Enum + Validation 的个人最佳实践 demo 分享
Enum + Validation 的个人最佳实践 demo 分享
2022-07-07 15:39:00 【小水牛...】
前言
很多场景中我们需要校验前端传来的参数是否属于某个 Enum
值,分享一段个人最佳实践的 demo
:
Enum
的最简声明@OfEnum & OfEnumValidator
Test 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
的最佳实践分享
边栏推荐
- mysql实现两个字段合并成一个字段查询
- 管理VDI的几个最佳实践
- Flask搭建api服务
- LeetCode 1774. The dessert cost closest to the target price is one question per day
- SlashData开发者工具榜首等你而定!!!
- LeetCode1051(C#)
- 麒麟信安操作系统衍生产品解决方案 | 存储多路径管理系统,有效提高数据传输可靠性
- 【饭谈】Web3.0到来后,测试人员该何去何从?(十条预言和建议)
- LeetCode 1986. The minimum working time to complete the task is one question per day
- On Apache Doris Fe processing query SQL source code analysis
猜你喜欢
mysql官网下载:Linux的mysql8.x版本(图文详解)
状态模式 - Unity(有限状态机)
DevOps 的运营和商业利益指南
Reflections on "product managers must read: five classic innovative thinking models"
SlashData开发者工具榜首等你而定!!!
【网络攻防原理与技术】第6章:特洛伊木马
【TPM2.0原理及应用指南】 16、17、18章
网络攻防复习篇
自定义View必备知识,Android研发岗必问30+道高级面试题
Test case management tool recommendation
随机推荐
MRS离线数据分析:通过Flink作业处理OBS数据
LeetCode 1696. Jumping game VI daily question
skimage学习(2)——RGB转灰度、RGB 转 HSV、直方图匹配
Number of exchanges in the 9th Blue Bridge Cup finals
【Seaborn】组合图表:FacetGrid、JointGrid、PairGrid
QML初学
Jenkins发布uniapp开发的H5遇到的问题
AI来搞财富分配比人更公平?来自DeepMind的多人博弈游戏研究
无法链接远程redis服务器(解决办法百分百)
QML beginner
99% 用户在 Power BI 云端报表常犯错误
Mrs offline data analysis: process OBS data through Flink job
浅谈 Apache Doris FE 处理查询 SQL 源码解析
With the latest Alibaba P7 technology system, mom doesn't have to worry about me looking for a job anymore
LeetCode刷题day49
How to add aplayer music player in blog
数值 - number(Lua)
LeetCode 515(C#)
rpcms获取指定分类下的文章的方法
【饭谈】那些看似为公司着想,实际却很自私的故事 (一:造轮子)