`

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如何实现自定义注解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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

    主要介绍了Hibernate Validation自定义注解校验的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

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

    Hibernate Validator 是 Bean ... Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,下面这篇文章主要给大家介绍了关于如何自定义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

    spring boot validation参数校验实例分析

    主要介绍了spring boot validation参数校验,结合实例形式分析了spring boot validation进行数据有效性验证的相关操作技巧,需要的朋友可以参考下

    Android代码-Android表单校验功能

    The goal of this library is to help you in your development of validation forms. currently it works on follow entities: First name: if first name is blank or other than alphabets it will throw error....

    基于 SpringBoot + Vue 前后端分离开发的动态个人博客系统源码(适合全栈个人学习、毕设、二次开发迭代)

    面向AOP编程:通过自定义注解实现接口限流、操作日志记录等 …… 开发环境 工具:IntelliJ IDEA JDK 1.8 数据库:MySQL 8.0.15 项目构建:后端Maven、前端 Webpack 后端 Web框架:Spring Boot 安全框架:Spring ...

    Spring Boot 参数校验

    Bean Validation是Java定义的一套基于注解的数据校验规范。这里简单实现了Spring Boot 参数校验,包括自定义注解,分组校验,全局异常处理等

    api-doclet:Doclet 从 JAX-RS 2、BeanValidation、JavaDoc 标签收集各种信息

    ) 支持的注释: 标准方法代号 自定义方法指示符(注解 ) 参数@PathParam @QueryParam @FormParam @HeaderParam @CookieParam @MatrixParam @DefaultValue HTTP 正文有效负载尚不支持: @BeanParam BeanValidation...

    基于Swoole 4.5+实现的高性能、高灵活性的PHP协程框架.rar

    Hyperf 还提供了 `基于 PSR-11 的依赖注入容器`、`注解`、`AOP 面向切面编程`、`基于 PSR-15 的中间件`、`自定义进程`、`基于 PSR-14 的事件管理器`、`Redis/RabbitMQ/NSQ/Nats 消息队列`、`自动模型缓存`、`基于 ...

    apidog:Api Watch Dog, Hyperf 框架的 Api参数校验 和 swagger 生成组件

    在 1.2 版本后, 本扩展移除了内部自定义的验证器, 只保留的 hyperf 原生验证器, 以保持验证规则的统一旧版本文档安装composer require daodao97/apidog使用1. 发布配置文件...

    Struts2 in action中文版

    13.2.3 测试validation.xml文件 284 13.3 最大化重用 284 13.3.1 使用component标签组件化 285 13.3.2 重用模板化的标签 286 13.3.3 连接UI标签和对象 287 13.4 高级UI标签的使用 288 13.4.1 覆盖既有模板 288 ...

    fhs-framework快速开发平台.rar

            集成了validate-springboot-starter,在兼容hibernate Validator和javax validation的同时,支持了更多自定义玩法。 内置常用验证规则:比如手机号验证,正则验证,ip,邮箱,长度,范围,数字,小数...

    Hyperf协程框架-PHP

    11 的依赖注入容器、注解、AOP 面向切面编程、基于 PSR-15 的中间件、自定义进程、基于 PSR-14 的事件管理器、Redis/RabbitMQ/NSQ/Nats 消息队列、自动模型缓存、基于 PSR-16 的缓存、Crontab 秒级定时任务、...

    Java_EE_6规范中文版

    6.25 Java平台公共注解1.1标准 6.26 Persistence API 2.0 6.27 Bean Validation 1.0 6.28 Managed Beans 1.0 标准 6.29 Interceptors 1.1 标准 6.30 Contexts Dependency 6.31 Dependency Injection 第7章 互...

    Hyperf 协程框架 v2.1.10

    11 的依赖注入容器、注解、AOP 面向切面编程、基于 PSR-15 的中间件、自定义进程、基于 PSR-14 的事件管理器、Redis/RabbitMQ 消息队列、自动模型缓存、基于 PSR-16 的缓存、Crontab 秒级定时任务、Session、i18n ...

Global site tag (gtag.js) - Google Analytics