当前位置: 首页 > news >正文

自定义注解校验

在日常开发中经常会用到String类型的数据当作数值进行映射,势必会做出数值范围的校验,可以通过自定义注解的办法简化代码实现,减少冗余代码。 

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = StrRangeValidator.class)
public @interface StrRange {/*** 错误提示* @return*/String message() default "value is not in given range";/*** 最小值* @return*/double min() default Double.MIN_VALUE;/*** 最大值* @return*/double max() default Double.MAX_VALUE;/*** 是否包含边界* @return*/boolean closeMin() default true;/*** 是否包含边界* @return*/boolean closeMax() default true;/*** 是否可空* @return*/boolean nullable() default true;Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };
}

这里的groups,payload是必须的。其他方法是根据需要设定的参数:

1. 允许null值跳过校验

2. 边界值开区间、闭区间

3. 自定义errorMessage

validatedBy 是核心的验证逻辑:

public class StrRangeValidator implements ConstraintValidator<StrRange, String> {private boolean nullable;private BigDecimal min;private BigDecimal max;private boolean closeMin;private boolean closeMax;@Overridepublic void initialize(StrRange constraintAnnotation) {nullable = constraintAnnotation.nullable();min = new BigDecimal(String.valueOf(constraintAnnotation.min()));max = new BigDecimal(String.valueOf(constraintAnnotation.max()));closeMin = constraintAnnotation.closeMin();closeMax = constraintAnnotation.closeMax();}@Overridepublic boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {if (s == null && nullable){return true;}try {BigDecimal val = new BigDecimal(s);boolean checkMin = closeMin ? min.compareTo(val) <= 0 : min.compareTo(val) < 0;boolean checkMax = closeMax ? val.compareTo(max) <= 0 : val.compareTo(max) < 0;return checkMin && checkMax;} catch (Exception ex) {return false;}}
}

String到枚举值的反向解析和验证也是比较常见的问题,也可以通过自定义注解的方式简化此类解析判断。

再来一个枚举验证:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ValidEnumValidator.class)
public @interface ValidEnum {/*** 错误提示* @return*/String message() default "invalid enum value";/*** 目标类型* @return*/Class<?> target();/*** 是否可空* @return*/boolean nullable() default true;Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };
}
public class ValidEnumValidator implements ConstraintValidator<ValidEnum, String> {private Class<?> clazz;private boolean nullable;@Overridepublic void initialize(ValidEnum constraintAnnotation) {nullable = constraintAnnotation.nullable();clazz = constraintAnnotation.target();}@Overridepublic boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {if (!clazz.isEnum()) {return false;}if (s == null && nullable) {return true;}try {Method method = clazz.getDeclaredMethod("of", String.class);return method.invoke(null, s) != null;} catch (Exception e) {return false;}}
}

注意,枚举需要保持类型一致:String,都存在这样的of方法

@AllArgsConstructor
@Getter
public enum EAccountAuthTypeEnum {OPEN_ACCOUNT("1", "开户"),;private final String code;private final String msg;public static EAccountAuthTypeEnum of(String code) {return Arrays.stream(values()).filter(ele -> ele.getCode().equals(code)).findFirst().orElse(null);}
}

http://www.lryc.cn/news/312113.html

相关文章:

  • 由数据范围反推算法复杂度以及算法内容
  • js监听F11触发全屏事件
  • Seata 2.x 系列【1】专栏导读
  • fly-barrage 前端弹幕库(3):滚动弹幕的设计与实现
  • Mysql面试总结
  • 【深圳五兴科技】Java后端面经
  • 画图(ccf201409-2)解题思路
  • 蓝桥杯刷题(一)
  • 设计模式:策略模式 ⑥
  • 数据结构从入门到精通——顺序表
  • 001-CSS-水平垂直居中布局
  • 【[STM32]标准库-自定义BootLoader】
  • Spring Boot项目中不使用@RequestMapping相关注解,如何动态发布自定义URL路径
  • Vue中有哪些优化性能的方法?
  • Python pandas遍历行数据的2种方法
  • Spring之@Transactional源码解析
  • 第三届国际亲子游泳学术峰会,麒小佑为亲游行业提供健康解决方案
  • Python光速入门 - Flask轻量级框架
  • C/C++ 说说引用这玩仍是干啥的
  • swoole
  • kubectl基础命令详解
  • collection的遍历方式
  • SpringBoot中@Async使用注意事项
  • IEEE 802.11 RTS/CTS/BA/Management
  • 【风格迁移】对比度保持连贯性损失 CCPL:解决图像局部失真、视频帧间的连贯性和闪烁
  • 【C++】贪心算法
  • 记一次dockerfile无法构建问题追溯
  • React使用 useImperativeHandle 自定义暴露给父组件的实例方法(包括依赖)
  • yolov5v7v8目标检测增加计数功能--免费源码
  • JPA常见异常 JPA可能抛出的异常