validation实现自定义注解
程序员文章站
2022-06-22 15:38:47
...
java接口使用入参时经常会判断一些参数的校验规则,使用validation的标签判断能拦截大部分不符合要求的参数,如:notnull max min ...
而有些业务需求的判断也可以通过自定义的标签来实现
下面实现request入参:判断多个参数需要有至少一个不为空
pom依赖的包:
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.0.2.Final</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency>
自定义标签的实现:
package com.use; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import javax.validation.Constraint; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import javax.validation.Payload; import org.apache.commons.lang.StringUtils; import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl; @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = SimultaneousNotNull.BindChecker.class) @Documented public @interface SimultaneousNotNull { //该组检查不为空的参数共有几个 int checkCount(); String message() default "参数不能同时为空!"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; public static class BindChecker implements ConstraintValidator<SimultaneousNotNull, String> { private static final ReentrantLock LOCK = new ReentrantLock(); //全局统计打标签SimultaneousNotNull 的个数,用来跟checkCount判断是否可做最后一个判断 private static AtomicInteger atomicInteger = new AtomicInteger(0); //标记打标签SimultaneousNotNull是否有一个入参有值,只要一个有值置为true,即满足条件 private static AtomicBoolean atomicBoolean = new AtomicBoolean(false); /** * @see javax.validation.ConstraintValidator#initialize(java.lang.annotation.Annotation) */ public void initialize(SimultaneousNotNull constraintAnnotation) {} /** * @see javax.validation.ConstraintValidator#isValid(java.lang.Object, * javax.validation.ConstraintValidatorContext) */ public boolean isValid(String strValue, ConstraintValidatorContext context) { atomicInteger.getAndIncrement(); Map<String, Object> attributes = ((ConstraintValidatorContextImpl) context).getConstraintDescriptor().getAttributes(); String type = (String) attributes.get("type"); String message = (String) attributes.get("message"); int checkCount = Integer.parseInt(attributes.get("checkCount").toString()); //同步加锁 LOCK.lock(); try { if (StringUtils.isNotBlank(strValue)) { atomicBoolean.set(true); } //last one if (atomicInteger.get() == checkCount && !atomicBoolean.get()) { return false; } return true; } finally { if (atomicInteger.get() == checkCount) { atomicBoolean.set(false); atomicInteger.set(0); } // 释放锁 LOCK.unlock(); } } } }
request校验的实体
package com.use; import javax.validation.constraints.NotNull; public class BindCase{ @SimultaneousNotNull(checkCount = 2) private String customer; @SimultaneousNotNull(checkCount = 2) private String id; @NotNull private String name; public String getCustomer() { return customer; } public void setCustomer(String customer) { this.customer = customer; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
main方法
package com.use; import java.util.Iterator; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.groups.Default; public class Main { public static void main(String[] args) { BindCase case1 = new BindCase(); // case1.setCustomer("1"); Set<ConstraintViolation<BindCase>> constraintViolations = Validation.buildDefaultValidatorFactory().getValidator().validate(case1, Default.class); if (!constraintViolations.isEmpty()) { Iterator<ConstraintViolation<BindCase>> it = constraintViolations.iterator(); StringBuilder sb = new StringBuilder(); String msg; while (it.hasNext()) { sb.append(it.next().getMessage()); sb.append(","); } msg = sb.substring(0, sb.lastIndexOf(",")).toString(); System.err.println(msg); System.err.println("校验结束"); } } }
以上的业务逻辑实现主要是实现了javax.validation.ConstraintValidatorContext接口
如果有其它需求也可以参考实现自定义的校验标签
上一篇: PHP个人网站架设连环讲(一)
下一篇: sql语句中关于join的基本相关(一)