springboot validation 自定义验证注解
程序员文章站
2022-07-10 21:07:25
springbootvalidation 自定义验证注解...
springboot validation 自定义验证注解
应用:自定义注解对pojo进行检验
************************
相关类与接口
ConstraintValidator:自定义注解对应验证规则
public interface ConstraintValidator<A extends Annotation, T> {
default void initialize(A constraintAnnotation) {
}
boolean isValid(T var1, ConstraintValidatorContext var2);
}
第一个参数A表示验证注解,第二个参数T表示注解标注的对象
@Length
@Documented
@Constraint(
validatedBy = {}
)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Length.List.class)
public @interface Length {
int min() default 0;
int max() default 2147483647;
String message() default "{org.hibernate.validator.constraints.Length.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface List {
Length[] value();
}
}
LengthValidator:长度验证器
public class LengthValidator implements ConstraintValidator<Length, CharSequence> {
private static final Log LOG = LoggerFactory.make(MethodHandles.lookup());
private int min;
private int max;
public LengthValidator() {
}
public void initialize(Length parameters) {
this.min = parameters.min();
this.max = parameters.max();
this.validateParameters();
}
public boolean isValid(CharSequence value, ConstraintValidatorContext constraintValidatorContext) {
if (value == null) {
return true;
} else {
int length = value.length();
return length >= this.min && length <= this.max;
}
}
private void validateParameters() {
if (this.min < 0) {
throw LOG.getMinCannotBeNegativeException();
} else if (this.max < 0) {
throw LOG.getMaxCannotBeNegativeException();
} else if (this.max < this.min) {
throw LOG.getLengthCannotBeNegativeException();
}
}
}
************************
示例:定义类验证注解,检验price*amount、totalFee的差值
********************
validation 层
@CheckNum
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {CustomValidator.class})
@Target({ElementType.TYPE,ElementType.ANNOTATION_TYPE})
public @interface CheckNum {
String field();
String field2();
String field3();
String message() default "{org.hibernate.validator.constraints.Length.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
CustomValidator
public class CustomValidator implements ConstraintValidator<CheckNum, Object> {
private String field;
private String field2;
private String field3;
@Override
public void initialize(CheckNum constraintAnnotation) {
this.field=constraintAnnotation.field();
this.field2=constraintAnnotation.field2();
this.field3=constraintAnnotation.field3();
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
BeanWrapper beanWrapper=new BeanWrapperImpl(o);
Double price=Double.parseDouble(Objects.requireNonNull(Objects.requireNonNull(beanWrapper.getPropertyValue(field)).toString()));
Integer amount=Integer.parseInt(Objects.requireNonNull(Objects.requireNonNull(beanWrapper.getPropertyValue(field2)).toString()));
double totalFee=Double.parseDouble(Objects.requireNonNull(Objects.requireNonNull(beanWrapper.getPropertyValue(field3)).toString()));
return Math.abs(totalFee-price*amount)<0.01;
}
}
********************
pojo 层
Order
@Data
@CheckNum(field = "price",field2 = "amount",field3 = "totalFee",message = "totalFee 与 price*amount数值相差超过0.01")
public class Order {
private Double price;
private Integer amount;
private Double totalFee;
}
********************
controller 层
HelloController
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(@Validated Order order, BindingResult result){
System.out.println(order);
if (result.hasErrors()){
result.getAllErrors().forEach(error -> {
System.out.print("field:"+error.getObjectName());
System.out.println(" ==> message:"+error.getDefaultMessage());
});
}
return "success";
}
}
************************
使用测试
localhost:8080/hello?price=2&amount=8&totalFee=8
2020-07-15 11:53:21.378 INFO 340 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-07-15 11:53:21.382 INFO 340 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 4 ms
Order(price=2.0, amount=8, totalFee=8.0)
field:order ==> message:totalFee 与 price*amount数值相差超过0.01
本文地址:https://blog.csdn.net/weixin_43931625/article/details/107343789
推荐阅读
-
基于SpringBoot的操作日志管理(AOP+自定义注解方式)
-
springboot使用aop的学习--结合自定义注解校验登入
-
springboot validation 自定义验证注解
-
SpringBoot自定义注解在service层无法被SpringAOP拦截?
-
Springboot自定义注解实现简单的接口权限控制,替代Shiro/SpringSecurity
-
springboot aop 自定义注解方式实现一套完善的日志记录(完整源码)
-
Springboot学习笔记:添加自定义拦截器之验证签名
-
SpringBoot使用自定义注解实现简单参数加密解密(注解+HandlerMethodArgumentResolver)
-
springboot 自定义注解记录控制器执行时间(aop实现)
-
SpringBoot中自定义注解实现参数非空校验的示例