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接口
如果有其它需求也可以参考实现自定义的校验标签
相关推荐
本文将详细介绍如何在Java中使用Validation API实现自定义注解。 首先,我们来看如何定义一个自定义注解。自定义注解通常需要使用 `@Constraint` 注解,并指定一个实现 `ConstraintValidator` 接口的类来处理校验...
定义和实现完成后,我们可以在模型类或方法参数上使用自定义注解,Spring等框架会在执行前自动进行校验: ```java public class User { @Email private String email; } ``` 5. **异常处理** 如果校验失败...
Hibernate Validation自定义注解校验的实现 Hibernate Validation自定义注解校验的实现是指在Hibernate Validation框架中,使用自定义的注解来实现特定的校验逻辑。在本文中,我们将通过示例代码,详细地介绍如何...
在IT行业中,自定义注解和数据验证是提高代码可维护性和灵活性的重要手段。这篇博客“common(自定义注解校验数据有效性)”显然探讨了如何利用自定义注解来确保程序中输入数据的有效性。自定义注解是Java等编程语言...
创建自定义注解类似于创建接口,但需以`@`符号开头。下面是一个自定义注解`MethodInfo`的例子: ```java @Documented @Target(ElementType.METHOD) @Inherited @Retention(RetentionPolicy.RUNTIME) public @...
本文将详细介绍如何使用Java自定义注解实现前后台参数的校验。 首先,自定义注解的定义需要使用`@interface`关键字。在给出的代码示例中,我们看到一个名为`IsValidString`的自定义注解,它用于检查字符串是否包含...
Hibernate Validator 是 Bean ... Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,下面这篇文章主要给大家介绍了关于如何自定义hibernate validation注解的相关资料,需要的朋友可以参考下
12. **自定义注解**:除了预定义的注解,Hibernate Validation还支持创建自定义验证注解,以满足特定业务需求。 在实际开发中,使用这些注解可以有效地避免因为用户输入错误导致的程序异常,提高系统稳定性和用户...
classmate-0.8.0.jar、hibernate-validator-5.0.0.CR2.jar、hibernate-validator-annotation-processor-5.0.0.CR2.jar、jboss-logging-3.1.1.GA.jar、validation-api-1.1.0.CR1.jar
本文将深入探讨如何结合EasyExcel和Validation实现高效且准确的Excel导入导出与数据校验。 EasyExcel的优势在于其简洁的API设计和对内存的高效利用。它无需预先加载整个Excel文件到内存,而是采用流式读写,降低了...
Hibernate Validator是Bean Validation的参考实现,它提供了更丰富的功能,如国际化错误消息、自定义注解的元数据等。在实际项目中,我们通常会使用Hibernate Validator来实现Bean Validation。 七、总结 Bean ...
在本文中,我们将深入探讨如何将Spring Boot与MyBatis-Plus结合,实现用户登录功能,并结合MD5加密以及自定义的Validation校验器。Spring Boot以其简洁的配置和强大的功能,成为现代Java开发的首选框架,而MyBatis-...
这篇名为“通过Java注解实现安全控制”的博文主要探讨了如何利用Java注解来加强应用程序的安全性。 Java注解的定义通常以`@`符号开头,后面跟着注解的类型。例如,`@Override`用于确保方法覆盖父类的方法,`@...
Hibernate Validator提供了更多的自定义注解和更强大的功能,如`@Email`, `@Past`, `@Future`等,同时还支持表达式语言来实现复杂的验证逻辑。此外,它还可以无缝集成到Spring框架中,通过配置可以在控制器层或服务...
自定义校验器注解可以继承自 Hibernate Validator 的 ConstraintValidator 接口,并实现 validate 方法来实现自己的校验逻辑。 Hibernate Validator 是一个功能强大且灵活的参数校验框架,提供了一种简单而且高效的...
例如,创建一个自定义注解`@EmailUnique`,并实现对应的校验器: ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = EmailUniqueValidator.class) public @...
这包括创建自定义注解(注解类型)、定义验证逻辑(约束验证器)以及配置元数据(例如消息模板)。 **3. 验证上下文(Validation Context)** 验证时,会创建一个验证上下文,其中包含了待验证的对象、验证配置和...
- 注解配置:在Action类的属性上使用自定义注解,通过注解的`type`属性指定自定义校验器。 4. **编写Action及模型类** 在Action类中定义需要校验的字段,并在模型类(通常为POJO)中添加对应的属性。使用Struts2...
`@NotNull`注解确保`fname`字段不能为空,否则会在`fname`字段的错误信息中显示自定义的错误消息。 综上所述,这个实例展示了如何在Spring Boot、Spring MVC和Thymeleaf的环境中,利用Java Bean Validation标准进行...