许可优化
许可优化
产品
产品
解决方案
解决方案
服务支持
服务支持
关于
关于
软件库
当前位置:服务支持 >  软件文章 >  数据校验框架:fluent_validator运用过程详解

数据校验框架:fluent_validator运用过程详解

阅读数 3
点赞 0
article_banner

前言:  话说写这篇博客已经拖了很久了, 一直没写.  怎么说:懒.  年后回来就没正常过,今儿个怎么想起了写呢?  我能说吃蓝莓吃多了,拉肚子不?

上回书说到使用fluent_validator做有关于逻辑的统一校验,但事已至此, 其实最终由于产品形态不一, 还是没能形成一个校验模板. 不过,有关于fluent这个东西,还是可以一说的.

一、思想的转变历程

我最开始, 是希望用注解做基本的输入校验, 而用fluent这个东西,封装一个通用的校验器。  我为什么会这样想呢? 首先: 保险标的,要么是人、要么是物。  当为人的时候, 有几个通用的校验点: 1, 当证件 类  型为身份证, 可不必输入性别和年龄;2,校验投保人和被保人的年龄 ,其余的不说, 至少这两点是很基本的。  而当为物的时候, 通常会有2个基本校验点:1, 当被保标的同投保企业的时候,不必输入标的属性; 2,当标的物同标的时,可不必输入标的物。  

所以,我的想法是: 将其公有属性抽象在一个基类中, 编辑一个基于此类的统一校验器。  却结果, too young too simple

让我自己感觉自己很年轻的现象有:

1, 我以为可以抽象的基本属性, 其实并不是每款产品都有,甚至是双数的条件都达不到。  比如说基本输入校验里的 手机 短信校验码, 有的产品不需要, 有的产品需要,这时候,我根本不能在基类的这个字段上让其不能为空

2, 同样是年龄校验, 有的单位是周岁、有的单位是天, 呵呵哒,听说还有按月的

3, 我们当时要做的模板, 和我理解的模板不一样,我理解的是我编辑基础的类,可以复用可以继承。 然而, 由于产品形态的多样性, 我们只需要抽象出基本的 产品开发 步骤和规范即可。  目前的产品形态, 支持不了做更细化的模板封装。

二、后来的结果

每个需要逻辑校验的产品, 都各自有一个校验器, 而一些公用的方法,被整理为了工具类, 比如说通过身份证号获取性别、年龄等。

虽然说没有做成一个统一公用的校验器, 但对于校验这块内容, 比起之前一堆的if else嵌套在一起,现在显得更为有条理性

其具体应用,可以参考上一篇博客中的链接加以深入理解, 也可以在其GitHub介绍上加以学习。 以下贴以下目前产品中的相应应用:

public class BabyProposalValidator extends ValitatorUtils implements Validator<BabyProposalFacadeDTO> {    @Override    public boolean accept(ValidatorContext validatorContext, BabyProposalFacadeDTO babyProposalFacadeDTO) {        return true;    }     @Override    public void onException(Exception e, ValidatorContext validatorContext, BabyProposalFacadeDTO babyProposalFacadeDTO) {     }     @Override    public boolean validate(ValidatorContext context, BabyProposalFacadeDTO bo) {         //投保人校验        Boolean holderFlag = holderValidator(context, bo.getProposalHolderPerson(), 18, null, null);        if (holderFlag) {            //被保人校验            for (BabyProposalSubjectPersonMasterFacadeDTO subject : bo.getProposalSubjectPersonMasters()) {                Boolean subjectFlag = subjectValidator(context, subject, bo.getStartDate());                if (!subjectFlag) {                    return false;                }            }            return true;        }        return false;    }     /** * 被保人校验器 * * @param context 上下文 * @param subject 被保人数据 * @param subjectEndDate 被保人年龄计算截止日期 * @return 通过校验返回true */    private Boolean subjectValidator(ValidatorContext context, BabyProposalSubjectPersonMasterFacadeDTO subject, String subjectEndDate) {        Boolean certNoValidateRet = certNoValidator(context, subject.getCertType(), subject.getSex(),                subject.getBirthday(), subject.getCertNo(), "被");        if (certNoValidateRet) {            if(subject.getCertType()==1){                IDCodeInfo idCodeInfo = getIDCodeInfo(subject.getCertNo());                Integer sex = idCodeInfo.getSex();                subject.setSex(sex.equals(1) ? PolicyEnum.Sex.MALE.getCode() : sex.equals(0) ?                        PolicyEnum.Sex.FEMALE.getCode() : PolicyEnum.Sex.OTHER.getCode());                subject.setBirthday(LocalDate.parse(idCodeInfo.getBirth()).toDate());            }            if (Days.daysBetween(new LocalDate(subject.getBirthday()), new LocalDate()).getDays() < 90) {                context.addErrorMsg("被保人出生需满90天");                return false;            }            if (Years.yearsBetween(new LocalDate(subject.getBirthday()),                    LocalDate.parse(subjectEndDate.substring(0, 10))).getYears() > 10) {                context.addErrorMsg("被保人年龄需小于10周岁");                return false;            }            return true;        }        return false;    }     /** * 投保人校验器 * * @param context 校验上下文 * @param holder 投保人数据 * @param holderAgeMin 投保人最小年龄 * @param holderAgeMax 投保人最大年龄 * @param holderEndDate 计算截止日期 * @return 校验通过返回true */    private Boolean holderValidator(ValidatorContext context, BabyProposalHolderPersonFacadeDTO holder, Integer holderAgeMin, Integer holderAgeMax, Date holderEndDate) {        Boolean holderValidateRet = certNoValidator(context, holder.getCertType(), holder.getSex(),                holder.getBirthday(), holder.getCertNo(), "投");        if (holderValidateRet) {            if(holder.getCertType()==1){                IDCodeInfo idCodeInfo = getIDCodeInfo(holder.getCertNo());                Integer sex = idCodeInfo.getSex();                holder.setSex(sex.equals(1) ? PolicyEnum.Sex.MALE.getCode() : sex.equals(0) ?                        PolicyEnum.Sex.FEMALE.getCode() : PolicyEnum.Sex.OTHER.getCode());                holder.setBirthday(LocalDate.parse(idCodeInfo.getBirth()).toDate());            }            //校验投保人年龄            return holderAgeValidator(context, holder.getBirthday(), holderEndDate, holderAgeMin, holderAgeMax);        }        return false;    } }

魔法值是每个产品的不同点, 最开始这些参数都是从外传递的, 呃,后来整个就懒了嘛, 反正每个产品一个校验器,就直接写好了,嘿嘿(心情不好的时候, 写代码很是放纵,反正领导不会看我写博客叨叨,我无敌我怕谁)

使用示例:

        Result ret = FluentValidator.checkAll()                .on(bo, new BabyProposalValidator())                .doValidate()                .result(toSimple());         if (!ret.isSuccess()) {            return ResponseBzn.build("-1", ret.getErrors().get(0));        }

备注: 可以设置这个校验器执行的时机(通过when语句),也可以设置一些参数

三、个人总结

最近一直在做产品的代码重构和迁移, 发现一个问题: 我格局太小。  就拿这个校验器的封装为例, 我就一心想做一个通用的出来, 但事实上结合到产品形态,我这想法本身就不成熟。

当然,也不能说格局太小, 怎么说呢,也许是经历的太少了。  以前从来没有接触过保险产品, 也没有想到每个保险公司对接的产品都各有风格,甚至是同一保险公司对接的产品都各有风格,在只接触了少数合作公司和少数产品的基础上, 要去做一个通用的东西,总觉得不太现实,涵盖不了一些变态的东西。

总之: 多学习,多努力。  感谢现在的同事给我安排的工作, 因为我在完成的过程中, 对于保险产品的开发流程, 形态变化有了更深的理解。  最后,讲个笑话给大家听: 我也不知道我有一回是买啥了, 然后就告诉我免费送一份保险给我,让我填 信息 , 我了个去, 我一看就填个手机号,姓名,别的都没有了, 心里立马断定这玩意儿不靠谱!  ——职业病
免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删


相关文章
技术文档
QR Code
微信扫一扫,欢迎咨询~
customer

online

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 board-phone 155-2731-8020
close1
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

姓名不为空

姓名不为空
手机不正确

手机不正确

手机不正确
公司不为空

公司不为空

公司不为空