# validate-assists
**Repository Path**: sham2k/validate-assists
## Basic Information
- **Project Name**: validate-assists
- **Description**: 通用报文校验框架,支持配置模式和注解模式对对象或Map进行合法性校验。
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2025-08-12
- **Last Updated**: 2025-09-29
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# 验证辅助工具
本工具增强 `HibernateValidator` 的功能,支持以 ` Map ` 对象的 ` key ` 作为 ` field ` 定义约束,对 ` Map ` 对象的值进行验证。本工具典型应用场景是通过Map传递数据以减少值对象类数量和实现通用化通信时验证数据合法性。
## 1 快速入门
### 1.1 添加依赖
````
com.github.sham2k
validate-assists
0.2.5
````
### 1.2 配置验证约束
本工具通过自定义校验器( ` @ValueMap ` )扩展 HibernateValidator 功能,因此需在相应字段上添加约束注解,或通过XML文件定义相应字段的约束,具体定义方法参考 HibernateValidator 文档。
#### 1.2.1 待验证的类
````
@Data
public class PageQry
{
private String cmdCode;
private Map qryData;
}
````
* ` cmdCode ` : 请求编号,服务端据此判定 ` qryData ` 的具体内容和要调用的服务。
* ` qryData ` : 请求数据,这是由本工具验证的对象,其内容是动态变化的,由 ` cmdCode ` 决定。
#### 1.2.2 PageQry 约束配置
` PageQry ` 使用HibernateValidator标准配置,可以使用注解或XML文件配置,并由HibernateValidation读取与处理。
##### (1) 注解模式
````
@Data
public class PageQry
{
@NotNull
@Length(min = 7, max = 7, message = "cmdCode长度应是xxx.nnn格式!")
private String cmdCode;
@ValueMap(defineName = "cmd.001")
private Map qryData;
}
````
##### (2) XML文件模式
使用标准的HibernateValidator XML 配置文件,且应按HibernateValidator要求存放到相应的目录 ` META-INF ` 。
例如:
````
META-INF/page-qry-001.xml
META-INF/page-qry-002.xml
````
````
qryData
cmd.001
cmdCode长度应是xxx.nnn格式!
7
7
````
* 本例在 ` qryData ` 字段定义 ` ValueMap ` 约束,指示该字段由本工具进行验证。
* ` qryData ` 字段的组成项及约束定义,由名为 ` defineName ` 的元素值确定,本例中为 ` cmd.001 ` 。本工具自动从各约束配置中查找名为 ` cmd.001 ` 的约束集合,并使用它对 ` reqData ` 进行验证。
#### 1.2.3 qryData 约束配置
由于 ` qryData ` 的组成内容是变化的,无法使用注解模配置,只能使用XML文件配置。XML配置文件可以存放在类路径中或外部配置目录中,并由本工具进行读取和使用。
````
8
64
````
* 本文件格式和标准的HibernateValidator文件一致,只是目前没有包含 ` xmlns ` 等文件描述信息。
* 一个文件可以定义一个或多个 ` bean ` ,并通过 ` class ` 属性定义约束集合的名称。该名称应全局唯一,且和 ` PageQry ` 文件的定义一致。本工具据此确定要使用哪个约束集合对 ` qryData ` 进行验证。
* ` bean ` 的组成字段是变化的,由业务规则确定。
* 本例中, ` pageInfo ` 字段是对象,通过 ` ` 指示由HibernateValidator进行验证, ` whereBy ` 字段是MAP,通过 ` ` 指示由本工具进行校验,其校验规则的名称是 ` whereBy ` 。
### 1.3 初始化
初始化主要包括初始化验证工厂和读取定义的验证文件两个操作。执行初始化操作的时机通常在启动应用程序后且受理请求前进行,具体时机由应用程序自行确定。
#### 1.3.1 初始化验证工厂
应用程序创建验证工厂或使用已创建的验证工厂,并通过如下代码将验证工厂实例传递给本工具。本工具通过验证工厂获取系统定义的验证器及相关参数进行相关验证处理。
````
// ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
ValidatorManager.setValidatorFactory(validatorFactory);
````
#### 1.3.2 读取验证文件
通过如下代码读取验证文件。本工具将读取的验证文件内容存储在内存中备用(类似全局变量)。
````
ConfigManager.loadConfig("/app/config", "validation-cfg");
````
* ` config ` : 配置外置时,为存储配置文件的具体目录。如没有使用配置外置,本参数可以设置为 ` null ` 或 ` "" ` 。如该参数值为 ` null ` ,本工具自动尝试从环境变量 ` APP_CFG_HOME ` 和 ` CONFIG_HOME ` 获取值作为本参数的值。
* ` validation-cfg ` : 配置文件名标识。本工具自动扫描类路径和配置目录下文件名前缀是该标识或目录名是该标识的 ` .xml ` 文件。例如: ` validation-cfg/*.xml ` 、 ` validation-cfg*.xml ` 。
### 1.4 执行验证
使用 HibernateValidator 标准用法执行验证。验证过程中 HibernateValidator 自动调用本工具进行额外验证。
````
PageQry pageQry = new PageQry();
// ...
Set> resultSet = ValidatorManager.validate(pageQry);
checkResult(resultSet);
````
如应用程序启用 ` group ` 验证,由于本工具无法从 HibernateValidator 获取当前验证的 ` groups ` ,因此应在启动验证前,通过如下代码设置当前启用的 ` groups ` 。
````
ValidatorManager.setGroups(Default.class, SELECT.class);
Set> resultSet = ValidatorManager.validate(pageQry);
checkResult(resultSet);
````
或使用本工具作为验证过程的入口。例如:
````
Set> result = ValidatorManager.validate(pageQry, SELECT.class);
````
本工具将当前启用的 ` groups ` 存储在 ` ThreadLocal ` 变量中备用,并在验证结束时释放该数据。如期望主动释放该数据,可以使用如下代码:
````
ValidatorManager.setGroups(null);
````
## 2 典型使用
### 2.1 自动判定约束集合名
本工具支持通过 ` ${xxx} ` 形式的占位符从当前对象中获取属性值作为约束集合的名称,以简化约束的配置,适用于使用Map传递多种格式数据的场景。
例如:
#### 2.1.1 注解模式
````
@Data
@ValueMap(defineName = "${cmdCode}", targetName = "qryData")
public class PageQry
{
@NotNull
@Length(min = 7, max = 7, message = "cmdCode长度应是xxx.nnn格式!")
private String cmdCode;
private Map qryData;
}
````
* ` defineName = "${cmdCode}" ` :从PageQry对象中获取 ` cmdCode ` 属性的值,作为 ` defineName ` 的值。
* ` targetName = "qryData" ` : 对PageQry对象的qryData属性进行验证。此时,qryData属性上不必添加约束。
#### 2.1.2 XML 文件模式
````
qryData
${cmdCode}
cmdCode长度应是xxx.nnn格式!
7
7
````
* 给 ` / ` 添加 ` ValueMap ` 约束,并通过 ` targetName ` 元素设置要验证的属性,通过 ` ${cmdCode} ` 设置约束集合名。
* 本场景下,不必给 ` qryData ` 属性添加约束。
### 2.2 验证 MAP 实例
参考如下代码,直接使用约束集合验证 ` Map ` 实例或其他对象实例。使用本模式验证的对象,不需要按HibernateValidation定义约束。
````
Map value = new HashMap<>();
...
Set>> result = ValidatorManager.validate(value, "cmd.001");
if (result.isEmpty()) {
System.out.println("**** PASS");
} else {
System.out.println("**** FAIL");
result.forEach(System.out::println);
}
````
### 2.3 验证嵌套 Map
如拟验证的 MAP 实例的元素值是 Map 实例,则参考如下配置验证该嵌套的 Map 实例。
````
...
````
* 给嵌套的 MAP 字段添加 ` ` 约束,指示要验证本字段,并通过 ` name ` 属性指示约束集合的名称。
# 3 变更历史
## 2024-02-05 Version 0.1.0
### 新增
* 实现基本功能
## 2024-02-06 Version 0.2.0
### 新增
* 支持验证嵌套的 MAP 实例
## 2024-02-06 Version 0.2.1
### 修改
* 将 ` ValidatorManager ` 从包 ` io.github.sham2k.validation.config ` 迁移到 ` io.github.sham2k.validation.validator ` 。
## 2024-02-06 Version 0.2.2
### 新增
* 实现直接使用约束集合校验对象。
## 2024-02-06 Version 0.2.3
### 修改
* 重构校验方法,支持设置 ` targetName ` 参数。
## 2024-02-07 Version 0.2.4
### 修改
* 修正校验嵌套Map时路径名错误。
## 2024-02-20 Version 0.2.5
### 修改
* 修正读取校验定义文件时,对配置目录路径判断错误。
## 2025-09-28 Version 0.2.6
### 修改
* 完善`ParameterDefine`定义,支持如下两种定义形式:
````
8
...
64
````
## 2025-09-28 Version 0.2.7
### 修改
* 完善对 `null` 值数据项的检查。对非 `null` 值数据项,应添加 `@NotNull` 约束。