苦B程序员的数据验证之路

发生了什么事

在一次苦B程序员苦C程序员的结对编程中发生的一段对话

代码是这样的:

public void deleteAllExtendAclsFromContent(String contentId) throwsContentAclServiceException {

// 参数验证

if (StringUtils.isBlank(contentId)) {

logger.warn("参数异常,内容唯一标识为空");

throw new ContentAclServiceException("参数异常,内容唯一标识为空");

}

// 检查内容合法性

contentAclService.checkContentId(contentId);

contentAclCoreService.deleteAllExtendAclsFromContent(contentId);

}

苦C程序员:会什么你的每个方法都要去检查一下参数是不是null,参数是不是指定的几种可选数据?

苦B程序员:因为如果我不检查,后面的操作将会是对一个错误的对象进行,会影响程序的正确执行。

苦C程序员:但是这个方法应该只关注自己的业务逻辑而不应该做一些与业务无关的参数的正确性判断,否则这个方法可能10行中有7行都是做参数合法性验证,真正的业务可能只有3行,你不觉得这会很怪异吗?

苦B程序员:那我有什么办法,我的程序跑不下去了,测试来找我的麻烦了!

苦C程序员:我看你的每个方法都要对参数做合法性检查,那是否可以将这样一个行为提取出来使所有的方法在被调用之前让一个类去做参数的合法性检查,我们只要给参数一个说明比如这样

public void deleteAllExtendAclsFromContent(@NotEmpty(message="参数异常,内容唯一标识为空")
String contentId) throws ContentAclServiceException {

// 检查内容合法性

contentAclService.checkContentId(contentId);

contentAclCoreService.deleteAllExtendAclsFromContent(contentId);

}

苦B程序员:嗯,这样看起来很不错,我们可以利用spring的aop做个拦截,在所有的方法被调用前先让一个拦截器来检查所有的参数是否合法。

苦C程序员:对,我们就这样干。

没多久时序图片就出来了。

.

.

.

半天后,两个人只有一个想法,那就是太苦B了,这是一整个体系两个人一天怎么做的完?在项目的时间进度压力下两人只有放弃(看来很多情况下不是程序员不想把事情做好,时间、时间、还是时间),于是程序又回到了刚开始,并且他们不得不为这一次冒险所耽搁的时间去自己加班完成工作。

这样的事情发生的多了大家就再也不会想在项目里使用什么优美的方式或好的模式来编写与设计代码了,而是以完成功能为目地的编码。

回顾上面的对话我们发现

? 苦B程序员的做法,是为了防止程序出现异常而对输入参数为了检查。

? 苦C程序员的想法,是让这种检查工作不必分散到各业务方法中。

两个程序员都是想把程序做的更健壮、业务更清晰、职责更分明,但是由于客观的原因他们的努力失败了。

神的出现

继续上面,此时的苦C程序员依然没有放弃,他利用项目的空闲时间继续研究,他认为这种需求应该不只他一个人有,世界上还有那么多的苦X程序员,可能早就有人想到了这个需求,也许早就有人已经完成了这个工作,苦C程序员突然想起了spring的mvc中好像可以验证参数的正确性,于是他求助了万能的google大神,终于被他找了解决这个问题的究极方案。

当当当“JSR303”闪亮登场。http://jcp.org/en/jsr/detail?id=303

这个规范当前较好的实现是Hibernate Validatorhttp://www.hibernate.org/subprojects/validator.html并且也可较方便的与spring集成。此时的苦C程序员感觉到浑身充满了力量,他大叫一声“JSR303赐予我力量吧!Google,live
for ever
”。从此苦C程序员在开发这条苦B的不归路上走的更坚实了,因为他又多了一把称手的神器—“JSR303”。

苦B程序员和C程序员皈依了我神最终升华为苦A程序员

网上有这样一个例子https://github.com/ghillert/spring-hibernate-validator-sample,这里面就是讲述如何使用JSR303来验证方法参数的。这里面需要在spring中做如下配置

<bean id="validator"

class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

<beanclass="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>

关键就在MethodValidationPostProcessor这个类,它的作用就是给所有的标记了要做验证的接口添加一个org.springframework.validation.beanvalidation.MethodValidationInterceptor拦截器,这个拦截器会负责验证你所要验证的参数。

但这个拦截器会抛出一个org.hibernate.validator.method.MethodConstraintViolationException.MethodConstraintViolationException异常,对于有些人来说也许他们并不希望得到这样的异常,可能是因为这个异常长的太怪异,也可能是其它的原因,总之就是不希望用这个,他们希望自已来控制验证出错后的处理方式。谢天谢地这一切都是开源的(感谢天,感谢地,感谢Spring……熟悉的旋律出现在耳边),那么分析MethodValidationPostProcessor与MethodValidationInterceptor代码后我们可以很容易的做到这一点,聪明的程序员们应该很快就可以明白了。

苦C程序员以最快的速度将这个消息告诉了苦B程序员,苦B程序员得到这个消息后第一直觉就是要尽快将这个成果分享到整个团队中,于是不久后整个团队的成员都皈依了我神(JSR303)最终升华为了苦A程序员(为什么还是苦A程序员?因为还有新的麻烦会不断的出现,我勒个去……)。

时间: 2024-10-14 20:35:54

苦B程序员的数据验证之路的相关文章

好程序员大数据分享:Hbase精解

好程序员大数据分享:Hbase精解,为什么有hbase?hbase是什么?Hbase的架构. 一. 为什么有hbase? 数据量越来越大,传统的关系型数据库不能满足存储和查询的需求.而hive虽然能满足存储的要求,但是hive不能满足非结构化.半结构化数据的存储和查询. 二.hbase是什么? hbase是一个开源的.分布式的.多版本的.可扩展的非关系型数据库.hbase是bigtable的开源java版本,建立在hdfs之上,提供高可靠性的.高性能.列式存储.可伸缩.实时读写的nosql数据库

好程序员大数据学习路线之hive存储格式

好程序员大数据学习路线之hive存储格式,hive的存储格式通常是三种:textfile . sequencefile . rcfile . orc .自定义 set hive.default.fileformat=TextFile; 默认存储格式为:textfile textFile:普通文本存储,不进行压缩.查询效率较低.1.sequencefile:hive提供的二进制序列文件存储,天生压缩.sequeceFile 和 rcfile都不允许使用load方式加载数据.需要使用insert 方

好程序员大数据学习路线之hive表的查询

好程序员大数据学习路线之hive表的查询 1.join 查询 1.永远是小结果集驱动大结果集(小表驱动大表,小表放在左表). 2.尽量不要使用join,但是join是难以避免的. left join . left outer join . left semi join(左半开连接,只显示左表信息) hive在0.8版本以后开始支持left join left join 和 left outer join 效果差不多 hive的join中的on只能跟等值连接 "=",不能跟< &g

好程序员大数据学习路线分享hive的运行方式

好程序员大数据学习路线分享hive的运行方式,hive的属性设置: 1.在cli端设置 (只针对当前的session) 3.在java代码中设置 (当前连接) 2.在配置文件中设置 (所有session有效) 设置属性的优先级依次降低. cli端只能设置非hive启动需要的属性.(log属性,元数据连接属性) 查找所有属性: hive>set; 查看当前属性的值:通常是hadoop hive> set -v; 模糊查找属性: hive -S -e "set" | grep

好程序员大数据学习路线hive内部函数

好程序员大数据学习路线hive内部函数,持续为大家更新了大数据学习路线,希望对正在学习大数据的小伙伴有所帮助.1.取随机数函数:rand()语法: rand(),rand(int seed) 返回值: double 说明: 返回一个0到1范围内的随机数.如果指定seed,则会得到一个稳定的随机数序列select rand();select rand(10);2.分割字符串函数:split(str,splitor) 语法: split(string str, string pat) 返回值: ar

好程序员大数据学习路线分享高阶函数

好程序员大数据学习路线分享高阶函数,我们通常将可以做为参数传递到方法中的表达式叫做函数 高阶函数包含:作为值的函数.匿名函数.闭包.柯里化等等. 定义函数时格式:val 变量名 =?(输入参数类型和个数)?=>?函数实现和返回值类型和个数 "="表示将函数赋给一个变量 "=>"左面表示输入参数名称.类型和个数,右边表示函数的实现和返回值类型和参数个数 作为值的函数 定义函数 scala> val func = (x:Int) => x * x

好程序员大数据学习路线分享MAPREDUCE

好程序员大数据学习路线分享MAPREDUCE,需求:统计大量的文本文件中的单词出现的次数 1)整个运算需要分阶段 阶段一:并行局部运算 阶段二 :汇总处理,不同的阶段需要开发不同的程序 2)阶段之间的调用 3)业务程序(task程序)如何并发到集群并启动程序 4)如何监控task程序的运行状态,如何处理异常 ::这些问题是开发分布式程序都会面临的问题,完全可以封装成框架::MR 的结构 一个完整的MapReduce运行时有三类实例进程: 1)MRAppMaster : 负责整个程序的过程调度和状

好程序员大数据学习路线Hadoop学习干货分享

好程序员大数据学习路线Hadoop学习干货分享,Apache Hadoop 为可靠的,可扩展的分布式计算开发开源软件.Apache Hadoop软件库是一个框架,它允许使用简单的编程模型跨计算机群集分布式处理大型数据集(海量的数据).包括这些模块: Hadoop Common:支持其他Hadoop模块的常用工具. Hadoop分布式文件系统(HDFS?):一种分布式文件系统,可提供对应用程序数据的高吞吐量访问. Hadoop YARN:作业调度和集群资源管理的框架. Hadoop MapRedu

好程序员大数据学习路线分享Scala分支和循环

好程序员大数据学习路线分享Scala分支和循环3.3. 条件表达式表达式:一个具有执行结果的代码块.结果是具体的值或者() 表达式的思考方式:以表达式为中心的编程思想 1.表达式和语句的区别:表达式有返回值,语句被执行.表达式一般是一个语句块,执行后,返回一个值 2.不使用return语句,最后一个表达式即返回值 if/else表达式有值,这个值就是跟在if或者else之后的表达式的值 object ConditionDemo {def main(args: Array[String]){var