# purah
**Repository Path**: 521069205/purah
## Basic Information
- **Project Name**: purah
- **Description**: 应该是到目前为止最简单好用的java参数校验框架 ,弥补了大部分spring validation的缺点,扩展性非常之强
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2025-07-25
- **Last Updated**: 2025-07-25
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Purah-zh
应该是到目前为止最简单好用的java参数校验框架 ,**基本实现用注释级别的复杂度实现规则控制,** 把除了不能省略的校验逻辑之外的部分尽可能省略
使用方式与Spring Validation类似,可以通过在method的 param 上加@CheckIt注解来使用
但是相对于Spring Validation用group控制逻辑的方式,purah对逻辑的使用会简单很多
**简单是结果,不是选项**
应该有一些待发现的bug,还有一些缺少的单元测试和文档,会慢慢修复和补充
### 0 使用方法
maven 依赖
```xml
io.github.vajval.purah
purah
1.0.13
```
在启动类上增加注解
```java
@SpringBootApplication
@EnablePurah(checkItAspect = true)//加上这个注解,checkItAspect 默认为true,设置为false可以关闭切面校验
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
}
```
### 1 基础使用
例如要对输入的姓名进行 中文姓名检测,先定义必要的逻辑
```java
@PurahMethodsRegBean //将bean中有注解的函数注册为规则
public class checkBean {
@ToChecker("中文名字检测")// 将函数转换为规则并且注册
public boolean nameCheck(String name) {
//......
return true;
}
}
```
然后就可以像Spring Validation一样使用了,增加了@FillToMethodResult 注解可将检测结果填充到返回值中
* 不添加 `@FillToMethodResult`注解,失败会抛出 `MethodArgCheckException` 异常
* 添加 `@FillToMethodResult`注解,会将检测的结果保存到返回值中.返回类型需要满足 `boolean` 或者 `CheckResult` 或者 `MethodHandlerCheckResult`
```java
public void test(@CheckIt("中文名字检测") String name) { //失败抛出MethodArgCheckException
}
@FillToMethodResult
public boolean testB(@CheckIt("中文名字检测")String name) { //将CheckResult的isSuccess()boolean结果填充到返回值
return false;
}
@FillToMethodResult
public CheckResult testC(@CheckIt("中文名字检测")String name) { //将CheckResult 填充到返回值
return null;
}
```
同样支持不使用切面直接获取返回结果
```java
@Autowired
Purahs purahs;
public void test(String name) {
CheckResult checkResult = purahs.checkerOf("中文名字检测").check(name);// 不借助切面手动检测
}
```
`@ToChecker`自带一个自动null校验
```java
public @interface ToChecker {
String value();
AutoNull autoNull() default AutoNull.notEnable;
}
```
可以实现在入参为null时自动成功或失败,默认notEnable 即不对null进行自动处理
```java
@ToChecker(value = "auto_null_success", autoNull = AutoNull.success)// name为null,自动返回成功
public boolean auto_null_success(String name) {
return false;
}
@ToChecker(value = "auto_null_failed", autoNull = AutoNull.failed)// name为null,自动返回失败
public boolean auto_null_failed(String name) {
return true;
}
```
### 2 多字段联合校验
如果想对拥有 多个字段的进检测行
例如 检测手机号是否与地址相符合
```java
class People{
String phone;
String address;
String id;
People parent;
}
class User{
@TestAnn("123")
String phone;
String address;
String name;
}
@PurahMethodsRegBean
public class CheckBean {
@ToChecker("手机号所属地址检测")
public boolean phoneAddress(
@FVal("phone")String phone,//phone value
@FVal("phone")TestAnn TestAnn, //phone 字段上的注解,People为null,User为@TestAnn("123")
@FVal("address")String address //address value
){
//定义逻辑,想要获取值的字段应当有getter函数
//当user或者people对象为null时,所有字段被填充为null,但是注解的获取不受影响
return true;
}
}
```
###### 使用
```java
public void test(@CheckIt("手机号所属地址检测") People people) {
}
public void test(@CheckIt("手机号所属地址检测") User user) {
}
@FillToMethodResult
public boolean test(@CheckIt("手机号所属地址检测")User user) {
return null;
}
@Autowired
Purahs purahs;
public void test(User user) {
CheckResult checkResult = purahs.checkerOf("手机号所属地址检测").check(user);
}
```
`@FVal`中的字段必须要有getter函数,没有会被填充为null,如果入参对于一个字段有Field没getter的话,会在获取value时打印`warn`日志请注意
例如
```accesslog
2024-07-31 21:30:03.882 [main] WARN i.g.v.p.c.resolver.ClassReflectCache - set null value because not getter function for class class io.github.vajval.purah.util.TestUser, field: id
```
### 3 多规则组合校验
purah支持对将**任意多**种规则组合为新规则,也支持对特定符合要求的Field的值进行指定规则的校验
例如 在用户注册时, 同时对user的name进行 `中文名字检测` ,对user 进行 `手机号所属地址检测`
并且将其命名为`用户注册检查`
有3种方法
##### 第一种
###### 定义
```java
@PurahMethodsRegBean
public class checkBean {
@Autowired
Purahs purahs;
@ToChecker("用户注册检查")
public Checker,?> phoneAddress(){ //用combo打组合拳
return purahs.combo("手机号所属地址检测") //对user 进行`手机号所属地址检测`
.match(new GeneralFieldMatcher("name"),"中文名字检测") //对名字为name字段进行匹配,并且进行 "中文名字检测"
.mainMode(ExecMode.Main.all_success);//ExecMode.Main 下面有解释
}
//GeneralFieldMatcher 支持以 a.b.c 的多级匹配
//也支持 "childList#10.b.name" 这样的的带list参数的多级匹配
//也支持 "*" "child.*" "*.name" "*.na?e" 这样的通配符匹配
//也支持 "a.b.c|childList#10.b.name|*|*.name|*.na?e" 这样同时匹配多个字符串
//除了 GeneralFieldMatcher 还支持很多,很下面有介绍,也可以自定义
}
```
###### 使用
```java
public void reg(@CheckIt("用户注册检查") User user) {
}
```
对于多个规则的执行方法(ExecMode.Main),可以通过选择不同的类型来控制判断逻辑
```java
public class ExecMode {
// 对于被ignore的check,不被视为成功也不被视为失败,被视为没有检查,不参与组合判断
public enum Main {
// 全成功才行,有错不继续 = 快速失败
all_success(0),//默认值
// 全成功才行,有错也要检查完
all_success_but_must_check_all(1),
// 一个就行,有错不继续检查
at_least_one(2),
// 一个就行,有错也要检查完
at_least_one_but_must_check_all(3);
//......
```
##### 第二种 推荐
**本项目支持自定义语法,可以以不比注释复杂的方式指定逻辑**
purah自带了一个示例用的 `example:`语法
下面能直接实现上面的效果
```java
public void userReg(@CheckIt("example:1[手机号所属地址检测][name:中文名字检测]") User user) {
}
//example语法的实现详情见`ExampleCustomSyntaxCheckerFactory`
// 1是ExecMode.Main 中的 all_success_but_must_check_all
//第一个中括号里的是要对对象本身进行的检查
//第二个中括号里的是要对对象的指定字段进行检查,默认支持 abc*,abc?的简单通配符
```
实现自定义语法并不复杂,这是 `example:`的实现, 若想实际使用需要增加判断语法是否合规的逻辑
```java
@Override
public boolean match(String needMatchCheckerName) {
return needMatchCheckerName.startsWith("example:");
}
@Override
public Checker