老規(guī)矩先上鏈接
https://github.com/Ubitar/Capybara-Validator
引言
日常開發(fā)中卫病,我們通常會(huì)把較多的參數(shù)包裝在一個(gè)類里谎脯,例如:要提交的表單Bean類梨熙。那么肯定少不了對(duì)該Bean類內(nèi)變量數(shù)據(jù)的正確性校驗(yàn),對(duì)于校驗(yàn)方法你可以選擇簡單的if-else或者使用校驗(yàn)器。
創(chuàng)建庫的原由
比如 Hibernate Validator 的校驗(yàn)器,如果你寫過java后端肯定知道,該校驗(yàn)器使用的是注解的方式進(jìn)行校驗(yàn)規(guī)則標(biāo)注澈蚌,同時(shí)也具有分組校驗(yàn)、指定校驗(yàn)順序的功能灼狰,其提供的校驗(yàn)功能還是很強(qiáng)大的宛瞄。這個(gè)東西是后端專屬的交胚,如果不移植而直接應(yīng)用到Android上會(huì)有些不盡人意的地方:
1份汗、無法直接應(yīng)用到安卓國際化應(yīng)用的校驗(yàn)情況中去 其注解中的message(校驗(yàn)失敗返回消息)只能使用固定的,是編譯時(shí)寫入的字符內(nèi)容蝴簇,無法使用R.string這樣的資源(這個(gè)已經(jīng)有人進(jìn)行安卓版本的移植了裸影,可以去查找下)
2、分組校驗(yàn)不易維護(hù) Bean的分組校驗(yàn)是通過指定Groups類實(shí)現(xiàn)的军熏,隨著變量和分組增多,閱讀的難度很可能會(huì)大大增加
3卷扮、自定義校驗(yàn)器僅能判斷目標(biāo)字段 在校驗(yàn)判斷時(shí)無法結(jié)合其他字段一起做出判斷荡澎。
4、沒有提供校驗(yàn)結(jié)果Tag標(biāo)識(shí) 校驗(yàn)結(jié)果標(biāo)識(shí)只有message信息晤锹,沒有額外的標(biāo)識(shí)
這一切的矛頭都指向了注解校驗(yàn)的運(yùn)行方式摩幔。
換種實(shí)現(xiàn)方式
使用非注解的方式來實(shí)現(xiàn)檢驗(yàn)過程。校驗(yàn)的順序鞭铆、校驗(yàn)規(guī)則都按照所添加的校驗(yàn)規(guī)則rule
來線性運(yùn)行或衡。
comparator
//添加一個(gè)或多個(gè)校驗(yàn)規(guī)則
.addItem(new NotNullRule(rawBean1.getStr(), "str can't not be null","tag1"))
.validate();//確認(rèn)校驗(yàn)規(guī)則
校驗(yàn)后獲取校驗(yàn)結(jié)果焦影、校驗(yàn)標(biāo)識(shí)、校驗(yàn)的目標(biāo)字段封断。
IResult result = CValidator.valid(new RawValidation1(bean));//執(zhí)行校驗(yàn)斯辰,獲取結(jié)果
boolean hasError=result.hasError();
IReason reason = result.getReasonAtFirst();
String message = reason.getMessage();
IFieldRule<Object> rule = (IFieldRule<Object>) reason.getRule();
String tag = rule.getTag();
Object field = rule.getField();
導(dǎo)入
implementation 'com.ubitar.capybara:validator:1.0.4'
開始
1、創(chuàng)建目標(biāo)Bean類
public class RawBean1 {
private String str;
//some setter and getter
}
2坡疼、創(chuàng)建校驗(yàn)流程類
public class RawValidation1 extends BaseValidation<RawBean1> {
public RawValidation1(RawBean1 rawBean1) {
super(rawBean1);
}
@Override
public IResult<RawBean1> onValid(IComparator<RawBean1> comparator) {
RawBean1 rawBean1 = getRaw();
//Context context=getContext();
return comparator
//添加一個(gè)或多個(gè)校驗(yàn)規(guī)則
.addItem(new NotNullRule(rawBean1.getStr(), "str can't not be null","tag1"))
.validate();//確認(rèn)校驗(yàn)規(guī)則
}
}
3彬呻、執(zhí)行校驗(yàn),獲取結(jié)果
IResult result = CValidator.valid(new RawValidation1(bean));
//獲取第一個(gè)校驗(yàn)錯(cuò)誤原因
IReason reason = result.getReasonAtFirst();
//獲取原因信息
String message = reason.getMessage();
//獲取目標(biāo)規(guī)則柄瑰、標(biāo)識(shí)闸氮、目標(biāo)字段
IFieldRule<Object> rule = (IFieldRule<Object>) reason.getRule();
String tag = rule.getTag();
Object field = rule.getField();
//是否開啟快速校驗(yàn)
CValidator.valid(Raw bean,Boolean quickMode)
//非快速校驗(yàn)時(shí)獲取所有錯(cuò)誤原因
List<IReason> reasons = result.getAllReason();
更多校驗(yàn)規(guī)則
EmailRule、EqualsRule教沾、LengthRule蒲跨、MaxLengthRule、MinLengthRule授翻、MaxRule或悲、MinRule、NotEmptyRule藏姐、NotNullRule隆箩、NotSpaceRule、UrlRule
自定義校驗(yàn)
添加一個(gè)校驗(yàn)手機(jī)號(hào)的檢驗(yàn)規(guī)則
public class PhoneRule extends BaseRule<String> {
private String message;
public PhoneRule(@Nullable String field, String message) {
super(field);
this.message = message;
}
/**
* 校驗(yàn)的具體實(shí)現(xiàn)
*
* @return true :校驗(yàn)通過 false:校驗(yàn)不通過
*/
@Override
public boolean onMatchField(String field) {
if (field == null||field.length()<=0) return false;
return Pattern.matches( "^[1]\\d{10}$", field);
}
// 返回的錯(cuò)誤信息
@Override
public String getMessage() {
return message;
}
@Override
public String getTag() {
return tag;
}
}
使用
comparator.addItem(new PhoneRule(rawBean.getPhone(),"手機(jī)號(hào)格式不正確"))