当前位置: 首页 > 科技观察

程序员在写接口参数校验的时候,总是有太多ifelse?避免体力劳动的一种方法

时间:2023-03-18 20:27:03 科技观察

对于写Java的程序员来说,不管是写简单的界面,还是页面后台的穿梭,后台参数校验的功能都是整个代码中不可或缺的一部分。它可以从系统入口过滤掉一些非法数据,保证我们系统的稳定性。还记得刚进入Java写后端的时候,因为刚从Android转做后端开发,对点对点开发不是很熟悉。有一天,我们的架构师老大给我一个要求,要写一个接口给客户端调用。功能其实很简单:就是根据客户端传递的一些参数,查询数据库中的数据,然后返回给客户端。虽然我是后端新手,但写代码的基础毕竟还是有的!很快就做完了,自己测试通过了,马上提交了代码,还主动找我们老大做Codereview。我还指着我们老板表扬我,说我写的真快!没想到我们老大看了一眼就把我提交的代码打回去了。我记得我的代码几乎是这样写的:我问自己我写的代码有没有问题,于是我找老板问他如果我的代码没问题怎么办。我回电话了?只见老大无奈的看着我说:功能还行,就是字太难看了。好吧,我承认代码有点长,有点乱,但是是不是因为接口参数太多了,所以要一一查看?说到这里,老板微微一笑,说道:来,我教你一招。只见老大的手指上下飞舞,两三下我验证参数的代码就被删除了,重构后的代码瞬间刷新:老大得意的对我说:好看不?晚上加班不熟悉一下Spring的Validation机制吗?我的宝宝受苦了!让我们看看如何使用SpringValidation。首先添加POM依赖新建一个SpringBoot工程,在pom.xml文件中添加依赖:需要注意一点:如果我们的工程引入了spring-boot-starter-web依赖,会自动依赖spring-boot-starter-validation,我们不需要手动添加依赖,防止一些版本兼容问题。添加约束注解在接收参数的UserReq实体类对应的属性上添加约束注解:注意事项:每个约束注解都有一个message元素,用于校验失败时的提示信息。一个属性可以添加多个约束注解。所有注解都是相关的,必须全部验证。您可以使用正则表达式来验证参数。眼尖的同学可能会发现,上面代码中使用的约束注解,有的是引用自javax.validation.constraints包,有的引用自org.hibernate.validator.constraints包,这是怎么回事?说到这里,不得不提一下JSR-303,JSR-303是JAVAEE(现已更名为:JakartaEE)中的一个子规范,叫做BeanValidation,定义了一些实体和方法验证约束和接口规范,而HibernateValidator为BeanValidation规范中的所有内置约束注解提供了实现,同时也增加了一些额外的约束注解。BeanValidation中内置的约束注解:HibernateValidator中新增的约束注解:值得一提的是,HibernateValidator中新增的一些优秀的约束注解,如@Email、@NotEmpty、@NotBlank,已经被吸收到BeanValidation标准中在约束注解中,我们在代码中引入的时候尽量使用javax.validation.constraints包下的约束注解。如何使用它?我们已经修改了接收参数的实体类,但是还不能实现校验功能,还需要修改Controller:在接收方法的参数前面加上@Validated注解,当然你也可以加上@Valid注解获取参数验证结果,需要验证的参数后跟一个BingingResult类型的参数,用于绑定验证结果。关于第一点,@Validated注解是Spring框架提供的,可以说是参考了JSR-303规范标准,注解@Valid的封装可以提供分组校验等附加功能。其实任何以“Valid”开头的注解都可以达到同样的效果(至于原因,有机会专门写一篇文章,有兴趣的可以关注下)至于第二点,为什么验证结果会自动绑定到后面的BingingResult对象,这里面涉及到SpringDataBinder数据绑定相关的知识(后面会讲解,感兴趣的可以关注下),现在我们只需要知道如何写它。请求测试现在我们使用Postman工具来请求我们的接口:然后我们打断点调试bindingResult对象:可以看到bindingResult对象绑定成功,返回了三个属性校验失败的结果。分组校验我们在写业务的时候,通常会有一种情况:添加操作的时候通常不需要校验参数Id,修改或者删除操作的时候需要校验参数Id,那么对于同一个参数接收类UserReq,我们如何处理它?这很简单。首先,我们新建一个更新组,只需要一个普通的接口类:然后我们在UserReq类中添加一个id属性,并添加@NotNull组验证:组支持传入一个数组,可以传入多个组。对于id属性,我们需要在更新和删除操作时验证这个属性。最后在Controller中的update接口方法中添加验证组:我们只需要在注解中添加需要验证的Update组即可。