5 Star 33 Fork 5

藏经阁 / chungkui

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

钟馗

介绍

钟馗是一款java数据校验框架,支持注解式数据校验,可以对系统中的各种接口,请求进行,入参校验,流控,防重等校验。 同时支持运行时动态改变校验规则;和spring注解式数据校验的区别是,校验规则纯文本化,方便校验逻辑集中在一处进行配置管理, 更像是一种语法糖 。 目前支持的校验模式有spring mvc模式,方法单个map入参模式,方法单个json入参模式,方法列表模式等等 ; 在当下前后端分离,微服务,api接口越来越常见的背景下,希望你会喜欢这样一款校验插件;

首先我不建议你直接读文档,建议你下载下来项目,运行demo中的applicat#main 访问:127.0.0.1:8080 体验下使用钟馗的方式和效果,看看是否喜欢,然后决定是否继续读文档

一、如何使用:

可以参考demo项目

第一步:初始化

引入jar包

   <dependency>
               <groupId>com.chungkui</groupId>
               <artifactId>check</artifactId>
               <version>0.0.7.2-RELEASE</version>
    </dependency>

1.实现AbstractCheckConfigCacheService,2.继承ChungkuiCheckConfig类并把bean注入spring容器;例如注解式配置如下(xml模式同理):

public class CheckConfigCacheServiceImpl extends AbstractCheckConfigCacheService {
   
   public void change() {
           clear();
   }

   @Override
   public String remoteGet(String s, String s1) {
       return null;
   }
}
@Configuration
public class CheckConfig extends ChungkuiCheckConfig {
   @Bean
   ExpressionsCacheService expressionsCacheService() {
       return new CheckConfigCacheServiceImpl();
   }

}

第二步:配置校验规则

在方法上面加上@Check注解,配置格式为json;如下:


public class controller {
     @Check({"{rule:'long(a)+long(b)>0',msg:{fail:'不通过',error:'数据格式不正确'},code:'500'}"
	 ,"{param:'a',type:'int',min:1,max:2,msg:'int不通过'}"})
     @RequireMaping
     public Object methodName(){
         return "jason";
     }
}

二、校验规则具体配置方法

有两种配置方式:

a.通过注解配置项value

该配置项为一个数组。每个参数是数组的一个元素。方便复用校验配置

b.通过注解配置项rules

整个配置项为一个json字符串,复用性差。但是方便进行远程管理所有配置项。有问题时方便拷贝整个配置进行修改

1.表达式校验:aviator


@Check({"{condition:'str.isNotEmpty(a)',rule:'long(a)>long(b)',msg:{fail:'校验不通过',error:'数字格式不正确'},code:500}"})

配置项含义:

key 描述
type 校验类型不配置表示aviator
rule 表达式具体配置方式参考官网
min 最小长度
max 最大长度
msg 校验失败提醒
code 失败编码
condition 触发条件,当表达式为true时才会校验

提示项含义

配置方法为把msg配置为json格式,如下。

@Check({"{rule:'long(a)>long(b)',msg:{fail:'校验不通过',error:'数字格式不正确'},code:500}"})
key 描述 default
fail 校验不通过
error 数据格式不正确报错

2.非空校验:require

@Check({"{type:'require',min:1,max:2,param:'c',msg:'require不通过'}"})
 

配置项含义:

key 描述
type 校验类型
rule 校验规则
param 参数名
min 最小长度
max 最大长度
msg 校验失败提醒
code 失败编码
condition 触发条件,当表达式为true时才会校验

智能提示

配置方法为把msg配置为json格式,如下。

@Check({"{type:'require',min:1,max:2,param:'c',msg:{min:'长度不可小于1',max:'长度不可大于20',null:'不可以为空值'}}"})
key 描述 default
min 最小值不满足提示 最小值超限
max 最大值不满足提示 最大值超限
null 格式不满足提示 参数必填

3.数字校验:int/double/long

规则格式

@Check({ "{type:'int/double/long',min:1,max:2,param:'a',msg:'int不通过'}"})

配置项含义:

key 描述
min 最小值
rule 校验规则
max 最大值
msg 校验失败提醒
code 失败编码
require 是否必填,true时候校验必填,fasle如果为空则不会校验值是否合法
condition 触发条件,当表达式为true时才会校验

智能提示

配置方法为把msg配置为json格式,如下。


@Check({ "{type:'int/double/long',min:1,max:2,param:'paramName',msg:{min:'不可小于1',max:'不可大于20',fai:'数字不合法'}}"})
key 描述 default
min 最小值不满足提示 最小值超限
max 最大值不满足提示 最大值超限
fail 格式不满足提示 参数不合法

4.json数组校验:jsonArray

@Check({"{type:'jsonArray',min:1,max:2,param:'c',msg:'require不通过'}"})

配置项含义:

key 描述
type 校验类型
rule 校验规则
param 参数名
min 最小个数
max 最大个数
msg 校验失败提醒
code 失败编码
condition 触发条件,当表达式为true时才会校验

智能提示

配置方法为把msg配置为json格式,如下。


@Check({"{type:'jsonArray',min:1,max:2,param:'c',msg:{min:'长度不可小于1',max:'长度不可大于20',null:'不可以为空值'}}"})
key 描述 default
min 最小值不满足提示 元素个数不足
max 最大值不满足提示 元素个数超限
null 格式不满足提示 参数必填

5.日期校验:date

@Check({"{type:'date',fmt:'yyyyMMdd HHmmss',before:2,after:3,param:'startTime',msg:'日期非法'}"})

配置项含义:

key 描述
type 校验类型
rule 校验规则
param 参数名
fmt 日期格式
before 早于当前时间毫秒数
after 晚于当前时间毫秒数
code 失败编码
condition 触发条件,当表达式为true时才会校验

6.日期跨度校验:dateInterval

@Check({"{type:'dateInterval',fmt:'yyyyMMdd HHmmss',maxInterval:2,minInterval:3,start:'startTime',end:'endTime',msg:{minInterval:'时间间隔太小',maxInterval:'时间间隔太长'}}"})

配置项含义:

key 描述
type 校验类型
start 开始时间参数名
end 结束时间参数名
require 是否必填
param 参数名
fmt 日期格式
maxInterval 最大跨度毫秒数
minInterval 最小跨度毫秒数
code 失败编码
condition 触发条件,当表达式为true时才会校验

6.防重校验

开启方式为

实现ReSumitWallCacheService接口实现。并注入spring中。推荐实现时使用redis.

例如:

@Service
public class ReSumitWallCacheServiceImpl implements ReSumitWallCacheService {
    @Override
    public boolean set(String s, String s1, int expire) {
        return CacheUtils.set(s, "01", expire, CacheUtils.ExPx.EX, CacheUtils.NxXx.NX);
    }
}

使用时配置项为reSubmitWall,配置格式如下。 调用方需要在入参中传入reSubmitWall(一个防重的token值,业务系统自发生成保证适当场景的唯一性。)

@Check(reSubmitWall = "{expire:2,prefix:'缓存前缀',msg:{null:'reSubmitWall不可传空',fail:'请勿重复提交'}}")

配置项含义:

key 描述
expire 防重token过期时间
msg 校验失败提醒
prefix token前缀,prefix=off表示关闭重复提交校验(开启配置中心时可用)

msg配置项含义:

key 描述
null token为空提醒
fail 重复提交提醒

6.单机版流控校验

配置方式为注解中的rateLimters项

@Check(rateLimters = {"{rate:1,msg:'流控',code:500}"})

配置项含义:

key 描述
rate 流控tps值
model 模式,动态:dynamic,静态:不配置
param 动态流控参数
sync 是否直接阻塞方式执行;true,false,默认为false;为true时直接阻塞直到获得令牌,慎用
warmupPeriod 从冷却状态到达最大速率所需时间(s)
waitLimit 取令牌等待(阻塞)时间(s)默认0;sync为false时候才有效;为 0的时候取不到令牌直接返回;
createRate 单位时间内动态流控对象生成速率
code 失败编码
msg 校验失败提醒
code 失败编码

7.集群版流控校验

配置方式为注解中的redisRateLimters项

    @Check(redisRateLimters={"{capacity:1,rate:1,perUser:1,msg:'您手速太快了,请稍后再试',code:500}"}

配置项含义:

key 描述
rate 流控tps值
param 动态流控参数
capacity 令牌桶容量
perUser 每次消耗令牌个数
code 失败编码
msg 校验失败提醒
code 失败编码

三、自定义msg格式

自定义格式注解配置项为msgTemp,格式必须为json,通过占位符的方式进行自定义 默认模板为{paramName:'#param',value:'#val',code:'#code',message:'#msg'}

例子:

@Check(msgTemp="{paramName:'#param',val:'#val',code:'#code',msg:'#msg'}")
描述
#param 入参名
#val 入参值
#code 失败编码
#msg 描述值

四、校验模式

目前支持三种校验模式mvc,mvc_html,args

默认的会自动探测校验模式,建议手动指定校验模式,效率更快。方法如下:

在注解中添加model项,可从枚举中获取支持的模式

 @Check(model = Model.MVC);
1.mvc模式:

校验request中的入参,校验失败无侵入代码直接响应json给客户端

2.mvc_html模式(不推荐):

校验request中的入参,校验失败,会缓存失败详情,可以通过如下方式获取校验结果,该种方式不会直接返回方法, 需要人工接收校验结果。使用场景是校验非ajax请求的场景

1.args模式:

从参数列表中取参数


boolean result=CheckResultContainer.check();//来在代码中获取是否校验通过;
Object msg=CheckResultContainer.getFailMsg();//来在代码中获取校验失败消息;

五、使用远程动态配置

使用远程配置,可以运行时修改校验规则,并且进行服务降级和流控等操作!(一般系统可能用不到的,可以不看)

如何配置:

自己继承AbstractExpressionsCacheService抽象类注入sping容器即可,实现remoteGet方法;获取远程配置需要你自己实现,这里返回远程配置的值即可;可以是从数据库查询的方式,或者配置中心获取的方式;

然后在你的配置改变之后请自行调用该bean类中的clear()方法;


public class DefaultExpressionsCacheServiceImpl extends AbstractExpressionsCacheService {
   @Override
     public String remoteGet(String s, String s1) {
                return  "返回数据库查询的值,或者配置中心的值即可";
     }
	 
	//当配置变化的时候自行调用clear()或者remoteSetCallBack(String remote, String val);
    public void remoteChange(String remote, String val) {
		//当配置变化的时候调用clear方法或者remoteSetCallBack清空或者刷新缓存
		clear();
    }
}

使用

a.注解上添加上remote配置项,指定远程的key,格式如下

@Check(remote="scm_validatekey"...)

b.然后你需要在你自己的服务中心(根据自己系统的实现做具体配置,可能是数据库配置,可能是配置中心配置),配置格式规则如下:和代码中配置类似,也是json格式

scm_validatekey={value:"[{type:'int/double/long',rule:{min:1,max:2,param:'a'},msg:{min:'不可小于1',max:'不可大于20',fail:'数字不合法'}}]"}

进行服务降级

同动态校验配置类似,在远端配置demoteConfig项即可

配置中心

scm_validatekey={demoteConfig:"{open:true,msg:'服务暂时不可使用请稍后重试',code:1000}"}

配置项含义

描述
open 是否开启降级,true表示开启
msg 降级触发拦截的时候的提示消息
code 降级触发拦截的时候的异常码

远程配置流控rateLimters

单机版

@Check(rateLimters = {"{rate:1,msg:'流控',code:500}"})

远程配置trafficControlConfig项即可

scm_validatekey={rateLimters : "{rate:100,param:'userName',msg:'流控命中服务暂时不可使用请稍后重试',code:10}"}

配置项含义

描述
rate 流控tps值
param 不为空表示根据参数动态流控,动态流控的时候会根据该参数进行动态流控
sync 是否直接阻塞方式执行;true,false,默认为false;为true时直接阻塞直到获得令牌,慎用
warmupPeriod 从冷却状态到达最大速率所需时间(s)
waitLimit 取令牌等待(阻塞)时间(s)默认0;sync为false时候才有效;为 0的时候取不到令牌直接返回;
code 失败编码
msg 校验失败提醒
code 失败编码

六、自定义流控

开启自定义流控

开启流控需要在spring 容器中实现TrafficControlService,并注入到spring容器中。

例如:

@Service
public class TrafficControlServiceImpl implements TrafficControlService {
    @Autowired
    private FlowControllerService flowControllerService;

    @Override
    public boolean check(String s) {
        return flowControllerService.check(s);
    }

    @Override
    public boolean dynamicCheck(String s, String s1) {
        return flowControllerService.dynamicCheck(s, s1);
    }
}

使用自定义流控

同动态校验配置类似,在配置中心配置项中添加trafficControlConfig;

在远程服务中配置

scm_validatekey={trafficControlConfig : "{key:'flow_control_key',param:'userName',msg:'流控命中服务暂时不可使用请稍后重试',code:1000}"}

配置项含义

描述
key 表示流控的配置中心key
param 不为空表示根据参数动态流控,动态流控的时候会根据该参数进行动态流控
msg 流控触发拦截的时候的提示消息
code 流控触发拦截的时候的异常码

七、参数为对象(json对象或者json数组等等)时的校验

可以对对象类型的数据中的字段进行校验;需要指定rules来进行校验,目前支持"(json),[json],javaBean,集合类型的对象等等"。 这里最初设计的时候我误入了一个误区,想要实现无限级嵌套,校验实现之后发现完全不好用,配置起来非常复杂。所以后来讨论后决定不做无限极嵌套, 如果你入参中对象深度较大。首先你应当考虑的是接口设计是否合理,如果必须这样做,那么建议你解析完成第一层后在另一个方法上做第二层的校验; 这样才是合理的。这是我折腾了很久之后想到的一点感悟;简单才是合理的。

(json)表示该对象是json对象[json]表示该对象是一个json数组 配置方式为:

//json对象
@Check(rules = "[{param:'userinfo',type:'(json)',msg:{error:'json格式不正确',null:'手机不可为空'},code:'500',rules:[{param:'username',type:'require',code:500,min:2,max:5,msg:{min:'手机名称太短',max:'手机名称太长',null:'不可为空'}}]}]")
//json数组
@Check(rules = "[{param:'param',type:'[json]',min:1,max:5,code:'500',msg:{min:'数组长度不足',max:'超长了',null:'数组不可为空'}, rules:[{param:'a',type:'require',min:2,max:5,msg:{min:'长度不足',max:'超长了',null:'不可为空'},code:500}]}]")

八、注意事项

ajax请求mvc的时候mvc返回值请使用Object,或者Map否则会出现类型转换异常

九、开发计划

开发辅助配置页面

十、架构:

默认规则引擎为aviator表达式引擎,另外提供必填和数字类型的定制化表达式引擎,定制化引擎支持更加完善的消息体系; 支持单个入参校验和多个参数之间进行表达式校验。 性能上通过把表达式预编译,放入LRU热点缓存的方式提高校验性能。

软件校验采用校验链的方式

校验链目前有四种。顺序分别为:

降级校验->流控校验->防重校验->参数校验;每个链路是否执行是可选的

两大引擎

规则解析引擎,

参数解析引擎

一个构造器

消息构造器

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

钟馗是一款java数据校验框架,支持注解式数据校验,可以对系统中的各种接口,请求进行,入参校验,流控,防重等校验。 同时支持运行时动态改变校验规则;和spring注解式数据校验的区别是,校验规则纯文本 展开 收起
Java 等 3 种语言
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/cangjingge/chungkui.git
git@gitee.com:cangjingge/chungkui.git
cangjingge
chungkui
chungkui
master

搜索帮助