`

validation实现自定义注解

    博客分类:
  • java
阅读更多

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如何实现自定义注解

    本文将详细介绍如何在Java中使用Validation API实现自定义注解。 首先,我们来看如何定义一个自定义注解。自定义注解通常需要使用 `@Constraint` 注解,并指定一个实现 `ConstraintValidator` 接口的类来处理校验...

    自定义校验注解框架(validator)

    定义和实现完成后,我们可以在模型类或方法参数上使用自定义注解,Spring等框架会在执行前自动进行校验: ```java public class User { @Email private String email; } ``` 5. **异常处理** 如果校验失败...

    Hibernate Validation自定义注解校验的实现

    Hibernate Validation自定义注解校验的实现 Hibernate Validation自定义注解校验的实现是指在Hibernate Validation框架中,使用自定义的注解来实现特定的校验逻辑。在本文中,我们将通过示例代码,详细地介绍如何...

    common(自定义注解校验数据有效性)

    在IT行业中,自定义注解和数据验证是提高代码可维护性和灵活性的重要手段。这篇博客“common(自定义注解校验数据有效性)”显然探讨了如何利用自定义注解来确保程序中输入数据的有效性。自定义注解是Java等编程语言...

    详解Java注解教程及自定义注解

    创建自定义注解类似于创建接口,但需以`@`符号开头。下面是一个自定义注解`MethodInfo`的例子: ```java @Documented @Target(ElementType.METHOD) @Inherited @Retention(RetentionPolicy.RUNTIME) public @...

    java自定义注解实现前后台参数校验的实例

    本文将详细介绍如何使用Java自定义注解实现前后台参数的校验。 首先,自定义注解的定义需要使用`@interface`关键字。在给出的代码示例中,我们看到一个名为`IsValidString`的自定义注解,它用于检查字符串是否包含...

    如何自定义hibernate validation注解示例代码

    Hibernate Validator 是 Bean ... Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,下面这篇文章主要给大家介绍了关于如何自定义hibernate validation注解的相关资料,需要的朋友可以参考下

    Hibernate Validation各注解的用法

    12. **自定义注解**:除了预定义的注解,Hibernate Validation还支持创建自定义验证注解,以满足特定业务需求。 在实际开发中,使用这些注解可以有效地避免因为用户输入错误导致的程序异常,提高系统稳定性和用户...

    自定义注解进行参数校验的jar包

    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和Validation实现高效且准确的Excel导入导出与数据校验。 EasyExcel的优势在于其简洁的API设计和对内存的高效利用。它无需预先加载整个Excel文件到内存,而是采用流式读写,降低了...

    Bean Validation技术实现对Javabean的校验

    Hibernate Validator是Bean Validation的参考实现,它提供了更丰富的功能,如国际化错误消息、自定义注解的元数据等。在实际项目中,我们通常会使用Hibernate Validator来实现Bean Validation。 七、总结 Bean ...

    springboot整合mybatis-plus 登录(md5加密)(validation自定义校验器)

    在本文中,我们将深入探讨如何将Spring Boot与MyBatis-Plus结合,实现用户登录功能,并结合MD5加密以及自定义的Validation校验器。Spring Boot以其简洁的配置和强大的功能,成为现代Java开发的首选框架,而MyBatis-...

    通过Java注解实现安全控制

    这篇名为“通过Java注解实现安全控制”的博文主要探讨了如何利用Java注解来加强应用程序的安全性。 Java注解的定义通常以`@`符号开头,后面跟着注解的类型。例如,`@Override`用于确保方法覆盖父类的方法,`@...

    Validation3个jia包 validation-api,hibernate-validator

    Hibernate Validator提供了更多的自定义注解和更强大的功能,如`@Email`, `@Past`, `@Future`等,同时还支持表达式语言来实现复杂的验证逻辑。此外,它还可以无缝集成到Spring框架中,通过配置可以在控制器层或服务...

    Hibernate validator使用以及自定义校验器注解

    自定义校验器注解可以继承自 Hibernate Validator 的 ConstraintValidator 接口,并实现 validate 方法来实现自己的校验逻辑。 Hibernate Validator 是一个功能强大且灵活的参数校验框架,提供了一种简单而且高效的...

    springmvc 使用validation使用的jar包!

    例如,创建一个自定义注解`@EmailUnique`,并实现对应的校验器: ```java @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = EmailUniqueValidator.class) public @...

    Bean Validation 技术规范特性概述

    这包括创建自定义注解(注解类型)、定义验证逻辑(约束验证器)以及配置元数据(例如消息模板)。 **3. 验证上下文(Validation Context)** 验证时,会创建一个验证上下文,其中包含了待验证的对象、验证配置和...

    Struts2自定义校验框架

    - 注解配置:在Action类的属性上使用自定义注解,通过注解的`type`属性指定自定义校验器。 4. **编写Action及模型类** 在Action类中定义需要校验的字段,并在模型类(通常为POJO)中添加对应的属性。使用Struts2...

    Springboot SpringMVC thymeleaf页面提交Validation实现实例.pdf

    `@NotNull`注解确保`fname`字段不能为空,否则会在`fname`字段的错误信息中显示自定义的错误消息。 综上所述,这个实例展示了如何在Spring Boot、Spring MVC和Thymeleaf的环境中,利用Java Bean Validation标准进行...

Global site tag (gtag.js) - Google Analytics